#include <iostream> using namespace std; int cas,t = 1,road[1001][1001],n,k,ra,rb,size[1001]; long long sum,dp[1001][1001]; //dp[i][j]表示从1到i节点有j个节点是其字数的最大值 void init() { int i,j; sum = 1; for(i = 1;i <= n;i ++) { sum = (sum*i)%1000000007; size[i] = 1; for(j = 1;j <= n;j ++) dp[i][j] = road[i][j] = 0; } } void LookRoad(int r) { int i; for(i = 1;i <= n;i ++) { if(road[r][i]) { road[r][i] = road[i][r] = 0; LookRoad(i); size[r] += size[i]; } } } int main() { cin >> cas; while(cas --) { cin >> n >> k; init(); for(int i = 1;i < n;i ++) { cin >> ra >> rb; road[ra][rb] = road[rb][ra] = 1; } LookRoad(1); dp[1][0] = ((n-1)*sum)/n; dp[1][1] = sum/n; for(int i = 2;i <= n;i ++) { for(int j = 0;j <= i;j ++) { if(j > 0) dp[i][j] = dp[i-1][j-1]/size[i] + (dp[i-1][j]*(size[i]-1))/size[i]; else dp[i][0] = (dp[i-1][0] *(size[i]-1))/size[i]; } } cout << "case #" << t ++ << ": " << dp[n][k] << endl; } return 0; }
时间: 2024-10-27 06:30:33