UVA11174 Stand in a Line

Stand in a Line

 

大意:有n个人排队,问有多少种排列使得没有人排在他的父亲前面

 

 

不难发现这是一个森林

设一个虚根root把所有树的根连起来,root排在所有方案的最前面,总方案数不变

设i的儿子为son1(i),son2(i)....sonk(i),k位i儿子的数量

设size[i]为i这棵子树的节点个数

f[i]为i这颗子树的方案数

f[i] = f[son1[i]] * f[son2[i]] * ... * f[sonk[i]] * (size[i] - 1) / (size[son1[i]]! * size[son2[i]]! * .. * size[sonk[i]]!)

相当于每颗子树内部排列:f[son1[i]] * f[son2[i]] * ... * f[sonk[i]]

然后把同一颗子树看做相同的排:(size[i] - 1) / (size[son1[i]]! * size[son2[i]]! * .. * size[sonk[i]]!)

 

把f[son1[i]]...f[sonk[i]拆开,带进去

发现size[i]!作为分母出现一次,(size[i]-1)!作为分母出现一次,约分得size[i]

于是f[root] = (size[root] - 1)!/(size[son1[i]] * size[son2[i]] * ... * size[sonk[i]])

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <vector>
  8 #include <cmath> 
  9 #define min(a, b) ((a) < (b) ? (a) : (b))
 10 #define max(a, b) ((a) > (b) ? (a) : (b))
 11 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
 12 inline void swap(long long &a, long long &b)
 13 {
 14     long long tmp = a;a = b;b = tmp;
 15 }
 16 inline void read(long long &x)
 17 {
 18     x = 0;char ch = getchar(), c = ch;
 19     while(ch < '0' || ch > '9') c = ch, ch = getchar();
 20     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
 21     if(c == '-') x = -x;
 22 }
 23 
 24 const long long INF = 0x3f3f3f3f;
 25 const long long MAXN = 100000 + 10;
 26 const long long MOD = 1000000007;
 27 
 28 struct Edge
 29 {
 30     long long u,v,nxt;
 31     Edge(long long _u, long long _v, long long _nxt){u = _u;v = _v;nxt = _nxt;}
 32     Edge(){}
 33 }edge[MAXN << 1];
 34 long long head[MAXN], cnt;
 35 inline void insert(long long a, long long b)
 36 {
 37     edge[++cnt] = Edge(a,b,head[a]);
 38     head[a] = cnt;
 39 }
 40 
 41 long long f[MAXN],t,n,m,b[MAXN],size[MAXN],fa[MAXN];
 42 
 43 void dfs(long long u)
 44 {
 45     size[u] = 1;b[u] = 1;
 46     for(register long long pos = head[u];pos;pos = edge[pos].nxt)
 47     {
 48         long long v = edge[pos].v;
 49         if(b[v]) continue;
 50         dfs(v), size[u] += size[v];
 51     }
 52     return;
 53 }
 54 
 55 long long pow(long long a, long long b)
 56 {
 57     long long r = 1, base = a%MOD;
 58     for(;b;b >>= 1)
 59     {
 60         if(b & 1) r *= base, r %= MOD;
 61         base *= base, base %= MOD;
 62     }
 63     return r;
 64 }
 65 
 66 long long ni(long long x)
 67 {
 68     return pow(x, MOD - 2);
 69 }
 70 
 71 int main()
 72 {
 73     read(t);
 74     f[0] = 1;
 75     for(register long long i = 1;i < MAXN;++ i)
 76         f[i] = (f[i - 1] * i) % MOD; 
 77     for(;t;--t)
 78     {
 79         memset(fa, 0, sizeof(fa));memset(head, 0, sizeof(head)), memset(b, 0, sizeof(b)), cnt = 0;
 80         read(n), read(m);
 81         for(register long long i = 1;i <= m;++ i)
 82         {
 83             long long tmp1,tmp2;
 84             read(tmp1), read(tmp2);
 85             insert(tmp2, tmp1);
 86             fa[tmp1] = tmp2;
 87         }
 88         for(register long long i = 1;i <= n;++ i)
 89             if(!b[i])
 90             {
 91                 int now = i;
 92                 while(fa[now]) now = fa[now];
 93                 dfs(now);
 94             }
 95         long long ans = 1;
 96         for(register long long i = 1;i <= n;++ i) ans *= size[i], ans %= MOD;
 97         printf("%lld\n", f[n] * ni(ans) % MOD);
 98     }
 99     return 0;
100 } 
UVA11174

 

posted @ 2018-01-18 17:09  嘒彼小星  阅读(311)  评论(0编辑  收藏  举报