大致題意:有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_pair
typedef 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("");
}
}