• 1382


    1382 - The Queue
    Time Limit: 2 second(s) Memory Limit: 32 MB

    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


    Problem Setter: Md. Arifuzzaman Arif
    Special Thanks: Jane Alam Jan
    题意:N个人,其中每个人都有一个上司,除了最高的上司。问将这些人排列,并且满足如果上司必须排在在他管辖的人的前面,问有多少种排列的方法。
    一开始想,这个有点像拓扑排序,然后再排列,后来感觉不对.
    思路:树形DP
    每个人只有一个上司,并且只有一个最大的boss,所以这些点可以构成一棵树。
    然后先考虑如果有一个根节点,下面有两个节点,那么我们可以把这三个合并成一个点,方案数为dp[v1]*dp[v2]*(C(size(v1)+size(v2,size(v1))));
    可以这样理解这个方程:dp[v1]是节点v1的合法的排列种数,同理dp[v2];那么当前的总个数为size[v1]+size[v2]+1;1为这两个点的上面的根节点,这样在合并的这些节点种取size[v1]个
    放v1下面的所有点那么剩下的就放v2所以合法数就是dp[v1]*dp[v2]*(C(size(v1)+size(v2,size(v1))));这样一直合并到boss就是最终结果;用dfs去实现dp复杂度O(n+E);
     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<string.h>
     5 #include<queue>
     6 #include<stack>
     7 #include<vector>
     8 using namespace std;
     9 typedef long long LL;
    10 const int N=1e9+7;
    11 vector<int>vec[1100];
    12 queue<int>que;
    13 int ans[2100];
    14 LL dp[1100];
    15 LL cnt[1100];
    16 LL ju[1100][1100];
    17 void dfs(int n);
    18 int main(void)
    19 {
    20         int k,i,j;
    21         ju[0][0]=1;
    22         ju[1][0]=1;
    23         ju[1][1]=1;
    24         for(i=2; i<=1099; i++)
    25         {
    26                 for(j=0; j<=i; j++)
    27                 {
    28                         if(i==j||j==0)
    29                                 ju[i][j]=1;
    30                         else  ju[i][j]=(ju[i-1][j]+ju[i-1][j-1])%N;
    31                 }
    32         }
    33         scanf("%d",&k);
    34         int s;
    35         int n,m;
    36         int x,y;
    37         for(s=1; s<=k; s++)
    38         {
    39                 for(i=0; i<1050; i++)
    40                 {
    41                         dp[i]=1;
    42                         vec[i].clear();
    43                 }
    44                 scanf("%d",&n);
    45                 for(i=1; i<=n; i++)
    46                         cnt[i]=i;
    47                 for(i=1; i<n; i++)
    48                 {
    49                         scanf("%d %d",&x,&y);
    50                         vec[x].push_back(y);
    51                         cnt[y]=x;
    52                 }
    53                 int id=1;
    54                 memset(ans,0,sizeof(ans));
    55                 for(i=1; i<=n; i++)
    56                 {
    57                         if(cnt[i]==i)
    58                                 id=i;
    59                 }
    60                 memset(ans,0,sizeof(ans));
    61                 dfs(id);
    62                 printf("Case %d: ",s);
    63                 printf("%lld
    ",dp[id]);
    64         }
    65         return 0;
    66 }
    67 void dfs(int n)
    68 {
    69         if(!vec[n].size())
    70         {
    71                 ans[n]=1;
    72                 dp[n]=1;
    73                 return ;
    74         }
    75         int cc=vec[n].size();
    76         int i,j;
    77         LL ak=0;
    78         ans[n]+=1;
    79         for(i=0; i<vec[n].size(); i++)
    80         {
    81                 dfs(vec[n][i]);
    82                 ans[n]+=ans[vec[n][i]];
    83                 dp[n]=(dp[vec[n][i]]*dp[n]%N)*(ju[ans[n]-1][ans[vec[n][i]]])%N ;
    84         }
    85 }
    油!油!you@
  • 相关阅读:
    Python遇到的零碎小问题
    【bug】YYC松鼠短视频系统V2.7版本以上 增加阿里云上传后,“上传视频无法生成缩略图报错” 修改
    【补丁】YYC松鼠短视频系统补丁,增加视频点赞数据管理功能,可修改点赞数量,V2.8的功能
    【bug】修复YYC松鼠短视频系统V2.7版本bug 注册输入验证码提示邀请码,输入邀请码提示错误
    YYC松鼠短视频系统【bug】短信验证码功能bug,新注册短信用户任意填写验证码都能通过注册的严重bug修复
    修复YYC松鼠短视频系统我的收藏页面 没有返回按钮的bug
    学好C++必须要注意的十八个问题
    es节点失效,手动重置primary,迁移分区
    elasticsearch 大集群最基本,也是最重要的两个配置gc和指针压缩
    2020年一整年几乎没有更新,重新开张
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5452131.html
Copyright © 2020-2023  润新知