Uva 11174 Stand in a Line
Stand in a Line Uva 11174
题意:把n个人排成一列,使得没有人排在他父亲的前面,输出方案数MOD 1000000007
思路:《算法竞赛入门经典》P 111
AC代码:
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<vector> #include<algorithm> #include<cstdlib> #include<cstring> #include<cmath> #include<string> using namespace std; const int N_MAX = 40000 + 20; const int MOD = 1000000007; typedef long long ll; int num[N_MAX];//记忆化搜索以,i为根节点的子树的节点数量 int e_gcd(int a,int b,int &x,int &y) { if (b == 0) { x = 1; y = 0; return a; } int ans = e_gcd(b,a%b,x,y); int temp = x; x = y; y = temp - a / b*y; return ans; } int mod_inverse(int a,int m) { int x, y; e_gcd(a,m,x,y); return (m + x%m) % m; } int n, m; vector<int>G[N_MAX]; int dfs(int x) {//寻找以x为根的子树的节点数量 if (num[x])return num[x]; for (int i = 0; i < G[x].size();i++) { num[x] += dfs(G[x][i]); } return ++num[x]; } int main() { int t; scanf("%d",&t); while (t--) { scanf("%d%d",&n,&m); memset(num,0,sizeof(num)); for (int i = 0; i <n; i++)G[i].clear(); for (int i = 0; i < m;i++) { int a, b; scanf("%d%d", &a, &b); a--, b--; G[b].push_back(a); } ll N = 1; for (int i = 2; i <= n;i++) { N = N*i%MOD; } ll mul = 1; for (int i = 0; i < n;i++) { mul = mul*dfs(i)%MOD; } ll ans = N*mod_inverse(mul, MOD) % MOD; printf("%lld\n",ans); } return 0; }