Light OJ 1382 The Queue(组合计数)

来源:互联网 发布:淘宝的电脑主机能买吗 编辑:程序博客网 时间:2024/05/16 14:29

On some special occasions Nadia's company provide very special lunch for all employees of the company. Before the food is served all of the employees must stand in a queue in front of the food counter. The company applied a rule for standing in the queue. The rule is nobody can stand anywhere in front of his supervisor in the queue. For example, if Abul is the supervisor of Babul and Abul stands in kth position from the front of the queue, then Babul cannot stand at any position in between 1 and k - 1 from front of the queue.

The company has N employees and each of them has exactly one supervisor except one (CEO) who doesn't have any supervisor.

You have to calculate in how many ways the queue can be created. For this problem, you can safely assume that in at least one way the queue can be created.

Input

Input starts with an integer T (≤ 700), denoting the number of test cases.

Each case starts with a line containing an integer N (1 ≤ N ≤ 1000). Each of the following N - 1 lines will contain two integers a and b (1 ≤ a, b ≤ N, a ≠ b), which denotes that a is the supervisor of b. For the sake of simplicity we are representing each employee by an integer number. Assume that the given input follows the restrictions stated above.

Output

For each case, print the case number and the number of ways to create the queue. The result can be large, print the result modulo 1000 000 007.

Sample Input

Output for Sample Input

1

5

2 1

2 3

3 4

3 5

Case 1: 8

 分析:给出a,b  a若是想监视b,则a必须在b前面分析下题目我们知道组成的肯定是树

对于以u为根节点的树来说,剩余可选的位置就是子树节点的和,那么对于某一课子树

来说,我们只需要依次从剩余的“位置”中选择子树节点个数出来即可

#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<string>#include<iostream>#include<queue>#include<cmath>#include<map>#include<stack>#include<set>using namespace std;#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define CLEAR( a , x ) memset ( a , x , sizeof a )const int INF=0x3f3f3f3f;typedef long long LL;const int maxn=1100;const int mod=1e9+7;vector<int>G[maxn];int d[maxn],in[maxn];LL ans[maxn];LL C[1010][1010];int t,n;void init(){    C[1][0]=C[1][1]=1;C[0][0]=1;    for(int i=2;i<=1000;i++)    {        C[i][0]=C[i][i]=1;        for(int j=1;j<i;j++)            C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;    }}int dfs(int u){    d[u]=1;    for(int i=0;i<G[u].size();i++)    {        int to=G[u][i];        d[u]+=dfs(to);    }    return d[u];}LL DFS(int u){    int s=d[u]-1;    ans[u]=1;    for(int i=0;i<G[u].size();i++)    {        int to=G[u][i];        LL res=(DFS(to)*C[s][d[to]])%mod;        ans[u]=(ans[u]*res)%mod;        s-=d[to];    }    return ans[u];}int main(){    int x,y,cas=1;    init();    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        CLEAR(in,0);        for(int i=0;i<=n;i++)            G[i].clear();        REP(i,n-1)        {            scanf("%d%d",&x,&y);            G[x].push_back(y);            in[y]++;        }        for(int i=1;i<=n;i++)        {            if(!in[i])            {                dfs(i);                printf("Case %d: %lld\n",cas++,DFS(i));                break;            }        }    }    return 0;}


0 0