[矩阵树定理][HEOI2015]小Z的房间

传送门

矩阵树定理:一张图的基尔霍夫矩阵即为其度数矩阵-邻接矩阵,度数矩阵中 D [ i ] [ i ] D[i][i] D[i][i]为点i的度
一张图的生成树个数即为其基尔霍夫矩阵的行列式

Code:

#include
#define int long long
#define N 90
#define mod 1000000000
using namespace std;
int n,m,f[N][N];
int tot,Map[N][N];

void add(int x,int y){
	if(x>y) return;
	f[x][x]++,f[y][y]++;
	f[x][y]--,f[y][x]--;
}
int Gauss(){
	int ans=1;
	for(int i=1;i<tot;i++){
		for(int j=i+1;j<tot;j++)
			while(f[j][i]){
				int t=f[i][i]/f[j][i];
				for(int k=i;k<tot;k++)
					f[i][k]=(f[i][k]-t*f[j][k]+mod)%mod;
				swap(f[i],f[j]);
				ans=-ans;
			}
		ans=(ans*f[i][i])%mod;
	}
	return (ans+mod)%mod;
}

signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		char c;
		for(int j=1;j<=m;j++){
			cin>>c;
			if(c=='.') Map[i][j]=++tot;
		}
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			int tem,u;
			if(!(u=Map[i][j])) continue;
			if(tem=Map[i-1][j]) add(u,tem);
			if(tem=Map[i+1][j]) add(u,tem);
			if(tem=Map[i][j-1]) add(u,tem);
			if(tem=Map[i][j+1]) add(u,tem);
		}
	printf("%lld\n",Gauss());
	return 0;
}

你可能感兴趣的:(矩阵树定理)