Leader in Tree Land
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 903 Accepted Submission(s): 438
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.
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
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
Author
UESTC
Source
2015 Multi-University Training Contest 7
Recommend
wange2014 | We have carefully selected several similar problems for you: 6361 6360 6359 6358 6357
这道题可以用概率dp做。
思路:
(由于没有用longlong,没有初始化tot,导致一直WA)
感觉这道题非常好!!!给图的作用就是求当前点为根点,在子树中是否为leader的概率
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1010;
#define mod 1000000007
int T,k,cas,tot;
int head[maxn*2];
ll siz[maxn];///以u为根节点的子树个数
ll inv[maxn];
ll dp[maxn][maxn];
struct node{
int v,next;
}edge[maxn*2];
void add(int a,int b){
edge[++tot].v=b;
edge[tot].next=head[a];
head[a]=tot;
}
void dfs(int v,int f)
{
siz[v]=1;
for(int i=head[v];i;i=edge[i].next)
{
if (edge[i].v!=f)
{
dfs(edge[i].v,v);
siz[v]+=siz[edge[i].v];
}
}
}
void dfs1(int u,int fa){
siz[u]=1;
for(int i=head[u];i;i=edge[i].next){
if(edge[i].v!=fa){
dfs(edge[i].v,u);
siz[u]+=siz[edge[i].v];
}
}
}
ll power(ll a,ll b)
{
ll ans=1,s=a;
while(b)
{
if (b&1)
ans=(ans*s)%mod;
b>>=1;
s=(s*s)%mod;
}
return ans;
}
int main()
{
int u,v,n,k;
cas=0;
for(int i=1;i<=1001;i++){
inv[i]=power((ll)i,mod-2);
}
scanf("%d",&T);
while(T--){
tot=0;
memset(head,0,sizeof(head));
memset(dp,0,sizeof(dp));
cas++;
scanf("%d%d",&n,&k);
for(int i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(1,0);
dp[0][0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<=i;j++){
dp[i][j]=(((dp[i-1][j]*(siz[i]-1))%mod)*inv[siz[i]])%mod;
dp[i][j]=(dp[i][j]+dp[i-1][j-1]*inv[siz[i]])%mod;
}
}
for(int i=1;i<=n;i++)
dp[n][k]=(dp[n][k]*i)%mod;
printf("Case #%d: %lld\n",cas,dp[n][k]);
}
}
/*
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
*/