[BZOJ5297][矩阵树定理]CQOI2018社交网络

版权声明:虽然博主很菜,但是还是请注明出处(我觉得应该没人偷我的博客) https://blog.csdn.net/qq_43346903/article/details/87871892

BZOJ5297

裸的矩阵树定理
注意高斯消元时可以把除法变成乘逆元

Code:

#include<bits/stdc++.h>
#define mod 10007
using namespace std;
inline int read(){
	int res=0,f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
	while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
	return res*f;
}
const int N=255;
inline int ksm(int x,int y){
	int res=1;
	for(;y;y>>=1){
		if(y&1) res=res*x%mod;
		x=x*x%mod;
	}
	return res;
}
int n,m,a[N][N],id[N],ans=1;
inline void Gauss(){
	for(int i=2;i<=n;i++){
		if(!a[i][i]){
			ans=mod-ans;
			for(int j=i+1;j<=n;j++) 
				if(a[j][i]){
					for(int k=i;k<=n;k++) swap(a[i][k],a[j][k]);
					break;
				}
		}
		if(!a[i][i]){ans=0;break;}
		ans=ans*a[i][i]%mod;
		int inv=ksm(a[i][i],mod-2);
		for(int j=i+1;j<=n;j++) if(a[j][i]){
			int res=inv*a[j][i]%mod;
			for(int k=i;k<=n;k++) a[j][k]=(a[j][k]+mod-a[i][k]*res%mod)%mod;
		}
	}
}
int main(){
	n=read(),m=read();
	for(int x,y,i=1;i<=m;i++){
		x=read(),y=read();
		a[y][x]++,id[x]++;
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++){
			if(i==j) a[i][i]=id[i];
			else a[i][j]=mod-a[i][j];
		}
	Gauss();
	cout<<ans<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43346903/article/details/87871892