UVa 12257 - The Queue

contents

  1. 1. Problem
  2. 2. Sample Input
  3. 3. Sample Output
  4. 4. Solution

Problem

不能站在自己的長官前面,求排列數有多少種,只會有一個人沒有長官,剩餘的人恰有一個長官。

Sample Input

1
2
3
4
5
6
1
5
2 1
2 3
3 4
3 5

Sample Output

1
Case 1: 8

Solution

將題目轉換成樹狀圖,因此考慮當前樹的情況,將子樹做重複排列的操作。

對於過大的組合採用費馬小定理計算結果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <string.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <iostream>
#include <map>
using namespace std;
#define MAXN 1024
const long long mod = 1000000007LL;
long long f[MAXN], invf[MAXN];
vector<int> g[MAXN];
long long dfs(int u, int &size) {
vector<int> subtree;
long long ret = 1;
int sum = 0;
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i], w;
ret = (ret * dfs(v, w))%mod;
subtree.push_back(w), sum += w;
}
size = 1 + sum;
ret = (ret * f[sum])%mod; // * n!
for (int i = 0; i < subtree.size(); i++)
ret = (ret * invf[subtree[i]])%mod; // / a!
return ret;
}
long long mpow(long long x, long long y, long long mod) {
long long ret = 1;
while (y) {
if (y&1)
ret = (ret * x)%mod;
x = (x * x)%mod, y >>= 1;
}
return ret;
}
int main() {
f[0] = 1, invf[0] = 1;
for (int i = 1; i < MAXN; i++) {
f[i] = (f[i - 1] * i)%mod;
invf[i] = mpow(f[i], mod - 2, mod);
}
int testcase, cases = 0, n;
int a, b;
scanf("%d", &testcase);
while (testcase--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
g[i].clear();
}
int indeg[MAXN] = {}, root = 0, w;
for (int i = 1; i < n; i++) {
scanf("%d %d", &a, &b);
g[a].push_back(b);
indeg[b]++;
}
for (int i = 1; i <= n; i++) {
if (indeg[i] == 0) {
root = i;
}
}
long long ret = dfs(root, w);
printf("Case %d: %lld\n", ++cases, ret);
}
return 0;
}
/*
*/