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;
}

 

posted on 2018-05-24 22:10  ZefengYao  阅读(180)  评论(0编辑  收藏  举报

导航