题目描述:
题解:
有向图矩阵树定理裸题。
与无向图区别是,对于一条边$(u,v)$,在基尔霍夫矩阵中令$a[v][v]++,a[u][v]--$。
同时以$k$为根时要扔掉第$k$行第$k$列。
代码:
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int N = 300; const int MOD = 10007; template<typename T> inline void read(T&x) { T f = 1,c = 0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();} x = f*c; } int n,m,hed[N],cnt; struct EG { int to,nxt; }e[N*N]; void ae(int f,int t) { e[++cnt].to = t; e[cnt].nxt = hed[f]; hed[f] = cnt; } ll fastpow(ll x,int y) { ll ret = 1; while(y) { if(y&1)ret=ret*x%MOD; x=x*x%MOD; y>>=1; } return ret; } ll inv(ll x){return fastpow(x,MOD-2);} ll a[N][N]; void Mod(ll&x){if(x>=MOD)x-=MOD;} ll gs() { ll ret = 1,f = 0; for(int i=2;i<=n;i++) { int tmp=i; for(int j=i+1;j<=n;j++) if(abs(a[j][i])>abs(a[tmp][i]))tmp=j; if(!a[tmp][i])return 0; if(tmp!=i) { f^=1; for(int j=i;j<=n;j++) swap(a[i][j],a[tmp][j]); } ret=ret*a[i][i]%MOD; ll now = inv(a[i][i]); for(int j=i;j<=n;j++) a[i][j]=a[i][j]*now%MOD; for(int j=i+1;j<=n;j++) { now = a[j][i]; for(int k=i;k<=n;k++) Mod(a[j][k]=a[j][k]-a[i][k]*now%MOD+MOD); } } if(f)ret=MOD-ret; return ret; } int main() { read(n),read(m); for(int u,v,i=1;i<=m;i++) { read(v),read(u); Mod(++a[v][v]); Mod(a[u][v]+=MOD-1); } printf("%lld ",gs()); return 0; }