树
感受
被题解惊呆了,真没想到可以转化为DFS序,然后在链上思考这个问题!
学到了
思路
首先我们要明确染色策略,按照DFS序染***r>当我们染色到u点时,假如我们已经使用了k种颜色。
按照DFS序染色的规则,我们可以发现,u点的子树并没有被染色,相反u的的父亲,父亲的父亲,...,都一定被染色了,至于它的兄弟也可能被染色。
所以,我们考虑给u染色时,如果u染的颜色来自那k种,那么染的颜色一定与父亲相同,否则,肯定可以从u的非子树部分找到一个点,其颜色与u相同,这样的话,根据树的性质,u必须经过父亲才能到达那个点,这样就会产生冲突。
如果染非k的颜色话,可以随便染,一定不会冲突。
因此,DP转移式子
-
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 300 + 10;
const ll mod = 1e9 + 7;
struct edge{
int v, nex;
}e[maxn * 2];
int head[maxn], cnt;
int n, k;
ll dp[maxn][maxn];
void add_edge(int u, int v){
cnt++;
e[cnt] = (edge){v, head[u]};
head[u] = cnt;
}
int main(){
scanf("%d%d", &n, &k);
int u, v;
for(int i = 1; i < n; i++){
scanf("%d%d", &u, &v);
//add_edge(u, v); add_edge(v, u);
}
dp[1][1] = k;
ll ans = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= k && i >= j; j++){
if(i == 1 && j == 1) continue;
dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] * (k - j + 1);
dp[i][j] %= mod;
if(i == n) ans += dp[i][j], ans %= mod;
}
}
printf("%lld\n", ans);
return 0;
}
360集团公司福利 406人发布