UVA 11174 - Stand in a Line(组合递归计数)

来源:互联网 发布:java 线程通信 编辑:程序博客网 时间:2024/06/05 05:40



大致题意:有n个人,给出m对关系,(a,b) 表示b是a的父亲, 现在有多少种方案使他们排成一列,使得没有人排在他们父亲前面

(对1e9+7取模)

思路:

可见,给出了一颗森林,对于每棵树,树根显然必须排第一位,然后对每棵子树用组合统计位置方案树,再乘以子树的子问题方案数。

到这里问题就算解决了,当然可以用dfs进行这种dp,但不妨人工迭代一下,每棵树的答案是 

ans = (cnt(root)-1)!  / ( cnt(son1)*cnt(son2)*... )  

然后再转化一下,加上虚根,把森林变成一颗树,这样得到的方案树仍然不变,因为根排列后必须占第一个位置,这样求解过程更简洁

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <cstring>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>#include <string>#include <vector>#include <cstdio>#include <ctime>#include <bitset>#include <algorithm>#define SZ(x) ((int)(x).size())#define ALL(v) (v).begin(), (v).end()#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)#define reveach(i, v) for (__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++ i)#define REP(i,n) for ( int i=1; i<=int(n); i++ )#define rep(i,n) for ( int i=0; i< int(n); i++ )using namespace std;typedef long long ll;#define X first#define Y second#define PB push_back#define MP make_pairtypedef pair<int,int> pii;template <class T>inline bool RD(T &ret) {        char c; int sgn;        if (c = getchar(), c == EOF) return 0;        while (c != '-' && (c<'0' || c>'9')) c = getchar();        sgn = (c == '-') ? -1 : 1 , ret = (c == '-') ? 0 : (c - '0');        while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');        ret *= sgn;        return 1;}template <class T>inline void PT(T x) {        if (x < 0) putchar('-') ,x = -x;        if (x > 9) PT(x / 10);        putchar(x % 10 + '0');}const int MOD = 1e9 + 7 ;const int N = 4e4+100;vector<int> G[N];ll inv[N] ;int qpow(int x) {int k = MOD - 2 ;ll ans = 1;ll m = x;while( k ) {if(k & 1) ans = (ans * m) % MOD ;k >>= 1;m = (m * m) % MOD;} return ans ;}ll c[N];void dfs(int u, int fa) {c[u] = 1;foreach(it, G[u]) {int v = *it;if( v == fa ) continue;dfs(v, u);c[u] += c[v];}}int main() {int T ;qpow(3);REP(i, N-10) inv[i] = qpow(i) ;RD(T);while(T --) {int n, m;RD(n), RD(m);REP(i, n) G[i].clear(), c[i] = 0;REP(i, m) {int u, fa;RD(u), RD(fa);G[fa].PB(u);}REP(i, n) if(!c[i]) dfs(i, 0);ll ans = 1;REP(i, n) ans = (ans * i) % MOD;REP(i, n) ans = (ans * inv[c[i]]) % MOD;PT(ans); puts("");}}




0 0
原创粉丝点击