https://ac.nowcoder.com/acm/problem/13611
因为树上的任意两个点都是可以两两联通的,而染色的过程就是构造联通快的过程,即将一颗树拆分成若干子树,所以这道题跟树的形态没有关系
我们考虑使用dp,dp[i][j]表示用i个点染j种颜色的方案数。每一个点跟前一个点的关系只有颜色相同、颜色不同两种,当颜色相同时,该点的方案数等于上一个点方案数,不同时只能使用剩余的k−j+1种颜色,于是我们可以得到状态转移方程:
dp[i][j]=dp[i−1][j]+dp[i−1][j−1]∗(k−j+1);
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
long long dp[405][405];
const ll mod=1e9+7;
int main()
{
int n,k;
scanf("%d%d",&n,&k);
dp[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=k;j++)
(dp[i][j]+=dp[i-1][j]+dp[i-1][j-1]*(k-j+1))%=mod;//第j个颜色选和不选
ll ans=0;
for(int i=1;i<=k;i++)
(ans+=dp[n][i])%=mod;
printf("%lld\n",ans);
}