题目链接:戳我
有向生成树计数。
那么在这里补充一下矩阵树定理吧!
- 度数矩阵-邻接矩阵(双向计数),去掉任意一行一列,剩下的式子高斯消元之后,对角线乘积是无向图的生成树个数。
- 入度矩阵-邻接矩阵(单向边),去掉根相关的一行一列,剩下的式子高斯消元之后,对角线乘积是外向树的生成树个数。
- 出度矩阵-邻接矩阵(单向边),去掉根相关的一行一列,剩下的式子高斯消元之后,对角线成绩是内向树的生成树个数。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 1010
#define mod 10007
using namespace std;
int n,m,ans=1;
int sum[MAXN][MAXN];
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&v,&u);
sum[v][v]++;
sum[u][v]--;
}
for(int i=2;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
while(sum[j][i])
{
int t=sum[i][i]/sum[j][i];
for(int k=i;k<=n;k++)
{
sum[i][k]=(sum[i][k]+mod-sum[j][k]*t%mod)%mod;
swap(sum[i][k],sum[j][k]);
}
ans*=-1;
}
}
}
for(int i=2;i<=n;i++) ans=1ll*ans*sum[i][i]%mod;
printf("%d
",(ans+mod)%mod);
return 0;
}