【BZOJ4894】天赋(外向树的矩阵树定理)

点此看题面

大致题意: 给定邻接矩阵,求该有向图以\(1\)号点为根的外向树个数。

矩阵树定理

关于矩阵树定理,可以看看这篇博客:初学矩阵树定理。(其实里面差不多啥都没有

这是一个结论题,对于外向树的生成数个数,就是入度矩阵-邻接矩阵的行列式的值。

证明?显然不会。。。。。。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 300
#define X 1000000007
#define Inc(x) (++x==X&&(x=0))
#define Dec(x) (!x--&&(x=X-1))
using namespace std;
int n,op,a[N+5][N+5];char s[N+5];
I int QP(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
I void Find(CI x)
{
	if(a[x][x]) return;RI i,j;for(i=x+1;!a[i][x];++i);
	for(j=x;j<=n;++j) swap(a[x][j],a[i][j]);op=X-op;//交换将op乘-1
}
int main()
{
	RI i,j;for(scanf("%d",&n),i=1;i<=n;++i)
		for(scanf("%s",s+1),j=1;j<=n;++j) s[j]=='1'&&(Inc(a[j][j]),Dec(a[i][j]));//入度矩阵-邻接矩阵
	RI k,t;for(op=1,i=2;i<=n;++i) for(Find(i),j=i+1;j<=n;++j)//高斯消元
		for(t=X-1LL*a[j][i]*QP(a[i][i],X-2)%X,k=i;k<=n;++k) a[j][k]=(1LL*t*a[i][k]+a[j][k])%X;
	RI res=op;for(i=2;i<=n;++i) res=1LL*res*a[i][i]%X;return printf("%d\n",res),0;//对角线上的积
}
posted @ 2020-06-09 19:31  TheLostWeak  阅读(21)  评论(0编辑  收藏