方法太屌,只能看一看了.....
可以用求概率的思想来解决这个问题。令以i号节点为根的子树为第i棵子树,设这颗子树恰好有sz[i]个点。那么第i个点是第i棵子树最大值的概率为1/sz[i],不是最大值的概率为(sz[i]-1)/sz[i]。现在可以求解恰好有k个最大值的概率。
令dp[i][j]表示考虑编号从1到i的点,其中恰好有j个点是其子树最大值的概率。 很容易得到如下转移方程:dp[i][j]=dp[i-1][j]*(sz[i]-1)/sz[i]+dp[i-1][j-1]/sz[i]。这样dp[n][k]就是所有点中恰好有k个最大值的概率。
题目要求的是方案数,用总数n!乘上概率就是答案。计算的时候用逆元代替上面的分数即可。
Leader in Tree Land
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 408 Accepted Submission(s): 166
Problem Description
Tree land has
n
cities, connected by
n−1
roads. You can go to any city from any city. In other words, this land is a tree. The city numbered one is the root of this tree.
There are n ministers numbered from 1 to n . You will send them to n cities, one city with one minister.
Since this is a rooted tree, each city is a root of a subtree and there are n subtrees. The leader of a subtree is the minister with maximal number in this subtree. As you can see, one minister can be the leader of several subtrees.
One day all the leaders attend a meet, you find that there are exactly k ministers. You want to know how many ways to send n ministers to each city so that there are k ministers attend the meet.
Give your answer mod 1000000007 .
There are n ministers numbered from 1 to n . You will send them to n cities, one city with one minister.
Since this is a rooted tree, each city is a root of a subtree and there are n subtrees. The leader of a subtree is the minister with maximal number in this subtree. As you can see, one minister can be the leader of several subtrees.
One day all the leaders attend a meet, you find that there are exactly k ministers. You want to know how many ways to send n ministers to each city so that there are k ministers attend the meet.
Give your answer mod 1000000007 .
Input
Multiple test cases. In the first line there is an integer
T
, indicating the number of test cases. For each test case, first line contains two numbers
n,k
. Next
n−1
line describe the roads of tree land.
T=10,1≤n≤1000,1≤k≤n
T=10,1≤n≤1000,1≤k≤n
Output
For each test case, output one line. The output format is Case #
x
:
ans
,
x
is the case number,starting from
1
.
Sample Input
2 3 2 1 2 1 3 10 8 2 1 3 2 4 1 5 3 6 1 7 3 8 7 9 7 10 6
Sample Output
Case #1: 4 Case #2: 316512
Source
/* ***********************************************
Author :CKboss
Created Time :2015年08月13日 星期四 10时59分40秒
File Name :HDOJ5378.cpp
************************************************ */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long int LL;
const int maxn=1100;
const LL mod=1000000007LL;
int n,k;
LL dp[maxn][maxn],sz[maxn];
vector<int> G[maxn];
void clear()
{
for(int i=0;i<=n+10;i++) G[i].clear();
}
LL dfs(int u,int fa)
{
sz[u]=1LL;
for(int i=0,ss=G[u].size();i<ss;i++)
{
int v=G[u][i];
if(v==fa) continue;
sz[u]+=dfs(v,u);
}
return sz[u];
}
LL inv[2*maxn],jc[2*maxn];
void init()
{
jc[0]=1; inv[1]=1;jc[1]=1;
for(LL i=2;i<2*maxn;i++)
{
inv[i]=(inv[mod%i]*(mod-mod/i))%mod;
jc[i]=(jc[i-1]*i)%mod;
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
init();
int T_T,cas=1;
scanf("%d",&T_T);
while(T_T--)
{
scanf("%d%d",&n,&k);
clear();
for(int i=0,u,v;i<n-1;i++)
{
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,1);
dp[0][0]=1LL;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=i;j++)
{
dp[i][j]=((dp[i-1][j]*(sz[i]-1))%mod*inv[sz[i]])%mod;
if(j) dp[i][j]=(dp[i][j]+(dp[i-1][j-1]*inv[sz[i]])%mod)%mod;
}
}
LL ans=(dp[n][k]*jc[n])%mod;
cout<<"Case #"<<cas++<<": "<<ans<<endl;
}
return 0;
}