1382 - The Queue

  PDF (English) Statistics Forum
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\n",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 }
时间: 2024-10-03 02:18:13

1382 - The Queue的相关文章

【BZOJ】1382: [Baltic2001]Mars Maps (线段树+扫描线)

1382: [Baltic2001]Mars Maps Time Limit: 5 Sec  Memory Limit: 64 MB Description 给出N个矩形,N<=10000.其坐标不超过10^9.求其面积并 Input 先给出一个数字N,代表有N个矩形. 接下来N行,每行四个数,代表矩形的坐标. Output 输出面积并 Sample Input 2 10 10 20 20 15 15 25 30 Sample Output 225 本以为是傻逼题,没想到不容易啊- 线段树+扫描

UVALive-7304 - Queue of Soldiers 【动态规划】【组合函数】【好题】

UVALive- 7304 - Queue of Soldiers 题目链接:7304 题目大意:士兵过山洞,必须以类似7 6 5 4 3 2 1顺序过.在第i个人之后,比i高的人都会被杀死,问如果要杀死k个人,有几种排队方法. 题目思路:先将士兵的身高离散化.假设N表示不同身高的数目.cnt[i] 表示i这个身高的人有多少个.(i的范围为1~N)sum[i]表示小于等于该身高段的士兵数目 然后开始dp,dp[i][j]表示已经到第i个士兵,已经死了j个人的方法数. 第三维遍历,q表示,第i+1

Java集合类: Set、List、Map、Queue使用

目录 1. Java集合类基本概念 2. Java集合类架构层次关系 3. Java集合类的应用场景代码 1. Java集合类基本概念 在编程中,常常需要集中存放多个数据.从传统意义上讲,数组是我们的一个很好的选择,前提是我们事先已经明确知道我们将要保存的对象的数量.一旦在数组初始化时指定了这个数组长度,这个数组长度就是不可变的,如果我们需要保存一个可以动态增长的数据(在编译时无法确定具体的数量),java的集合类就是一个很好的设计方案了. 集合类主要负责保存.盛装其他数据,因此集合类也被称为容

【译】RabbitMQ:工作队列(Work Queue)

在第一篇我们写了两个程序通过一个命名的队列分别发送和接收消息.在这一篇,我们将创建一个工作队列在多个工作线程间分发耗时的工作任务. 工作队列的核心思想是避免立刻处理资源密集型任务导致必须等待其执行完成.相反的,我们安排这些任务在稍晚的时间完成.我们将一个任务封装为一个消息并把它发送到队列中.一个后台的工作线程将从队列中取出任务并最终执行.当你运行多个工作线程,这些任务将在这些工作线程间共享. 这个概念对于在一个HTTP请求中处理复杂任务的Web应用尤其有用. 准备工作 在前一篇中,我们发送了一条

HDU 1908 Double Queue&lt;Set&gt;

Problem Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provided by IBM Romania, and using modern information technologies. As usual, each client of th

UVa 133 The Dole Queue

 The Dole Queue  In a serious attempt to downsize (reduce) the dole queue, The New National Green Labour Rhinoceros Party has decided on the following strategy. Every day all dole applicants will be placed in a large circle, facing inwards. Someone i

python线程队列---queue

queue队列 :使用import queue,用法与进程Queue一样 用法介绍: class queue.Queue(maxsize=0) #先进先出 import queue q=queue.Queue() q.put('first') q.put('second') q.put('third') print(q.get()) print(q.get()) print(q.get()) ''' 结果(先进先出): first second third ''' class queue.Lif

queue

queue是一种先进先出的数据结构.以下由简入繁引入queue. queue的操作主要有:入队,出队,空满判断等. 1. 数组实现简单队列 #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAX 10 int arr[MAX]; int head = 0; int tail = 0; int counter = 0; void enqueue(int value) { arr[tai

queue队列

今天有一个需求需要随时更新数据需要及时删除过期数据,就用到队列了.每执行一次定时任务就往queue中加一次数据,所以需要在一个独立于定时任务的类中加静态属性: public static Queue<CB_SingleDolaryToday> queue = new LinkedList<>() 因为需要求元素和所以加静态属性   public static double sumDolary = 0.0; 在定时任务中需要更新队列并删除过期元素 /*** 循环检测队列头元素,如果超