HDU 5378 Leader in Tree Land

来源:互联网 发布:mac如何复制粘贴文字 编辑:程序博客网 时间:2024/04/28 05:56

Leader in Tree Land

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 433    Accepted Submission(s): 173


Problem Description
Tree land has n cities, connected by n1 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 integerT, indicating the number of test cases. For each test case, first line contains two numbersn,k. Next n1 line describe the roads of tree land.

T=10,1n1000,1kn
 

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
23 21 21 310 82 13 24 15 36 17 38 79 710 6
 

Sample Output
Case #1: 4Case #2: 316512
 


这题的题意是给你一棵树,每个点分配一个1~N的值(每个点的值不同),对于这棵树tree[n],更新tree[i] = max(tree[i],tree[son[i][j]]),问最后可能的情况数


就是一个简单的树形dp,预处理组合数,暴力做,为了方便转移,我将这棵树转成了二叉树做

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;#define ls tree[o].l#define rs tree[o].r#define MOD 1000000007#define sf scanf#define LL long long#define maxn 1005LL dp[maxn][maxn];LL m,n,k;struct node {LL n,nxt;} e[maxn*2];LL p[maxn];void addedge(LL x,LL y) {e[m].n = y;e[m].nxt = p[x];p[x] = m++;}struct {LL l,r;LL cnt;void clear(){l=r = -1;cnt = 0;}} tree[maxn];LL C[maxn][maxn];void buildBitTree(LL o,LL fa) {bool flag = false;LL tmp = o;for(LL pp = p[o]; pp!=-1; pp = e[pp].nxt){if(e[pp].n!=fa) {if(flag) {tree[tmp].r = e[pp].n;} else {tree[tmp].l = e[pp].n;flag = true;}tmp = e[pp].n;buildBitTree(tmp,o);}}}LL dfs(LL o,LL k) {    if(k<=0 || k>tree[o].cnt) return 0;if(dp[o][k]!=-1) return dp[o][k];dp[o][k] = 0;if(ls==-1) {    if(rs==-1) dp[o][1] = 1;    else                dp[o][k] = C[tree[o].cnt][1] * dfs(rs,k-1) %MOD;}else{        if(rs==-1) dp[o][k] = ( dfs(ls,k) * (tree[o].cnt-1) + dfs(ls,k-1) ) % MOD;        else            for(LL i = 1;i <= tree[ls].cnt;i++)                dp[o][k] = (dp[o][k]                              + dfs(ls,i) * dfs(rs,k-i) % MOD * C[tree[o].cnt][tree[ls].cnt+1] % MOD * tree[ls].cnt % MOD//当前节点不算                              + dfs(ls,i) * dfs(rs,k-i-1) % MOD* C[tree[o].cnt][tree[ls].cnt+1] % MOD ) % MOD;}return dp[o][k];}void getCnt(LL o){    tree[o].cnt = 1;    if(ls!=-1) {getCnt(ls);tree[o].cnt+=tree[ls].cnt;}    if(rs!=-1) {getCnt(rs);tree[o].cnt+=tree[rs].cnt;}}int main() {C[0][0] = 1;for(LL i =1;i<=1000;i++)    {        C[i][0] = 1;        for(LL j = 1;j<i;j++)            C[i][j] = (C[i-1][j-1] + C[i-1][j])%MOD;        C[i][i] = 1;    }    LL T;sf("%lld",&T);LL CAS = 0;while(T--) {sf("%lld%lld",&n,&k);memset(dp,-1,sizeof dp);m = 0;memset(p,-1,sizeof p);memset(tree,-1,sizeof tree);for(int i = 0;i<maxn;i++) tree[i].clear();for(LL i = 1; i<n; i++) {LL x,y;sf("%lld%lld",&x,&y);addedge(x,y);addedge(y,x);}buildBitTree(1,-1);getCnt(1);LL ans = dfs(1,k);printf("Case #%lld: %lld\n",++CAS,ans);}return 0;}


0 0
原创粉丝点击