P4111 [HEOI2015]小Z的房间

思路

矩阵树定理的板子
注意不要把不会出现在生成树中的点放进矩阵中
然后消元要迭代的消,要注意返回值可能有负数

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#define int long long
using namespace std;
const int MOD = 1000000000;
int n,m,a[110][110],N,map[10][10];
char mat[10][10];
const int mx[]={0,-1,1,0},my[]={1,0,0,-1};
int guass(void){
	int ans=1;
	for(int i=1;i<N;i++){
		for(int j=i+1;j<N;j++){
			while(a[j][i]){
				int t=a[i][i]/a[j][i];
				for(int k=i;k<N;k++)
					a[i][k]=(a[i][k]-t*a[j][k]+MOD)%MOD;
				for(int k=1;k<N;k++)
					swap(a[i][k],a[j][k]);
				ans*=-1;
			}
		}
		ans=(ans*a[i][i]+MOD)%MOD;
	}
	return (ans%MOD+MOD)%MOD;
}
signed main(){
	scanf("%lld %lld",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%s",mat[i]+1);
		for(int j=1;j<=m;j++)
			if(mat[i][j]=='.')
				map[i][j]=++N;
	}	
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			for(int k=0;k<4;k++){
				if(!map[i][j])
					continue;
				int tx=i+mx[k],ty=j+my[k];
				if(tx<1||tx>n||ty<1||ty>m)
					continue;
				if(map[tx][ty]){
					a[map[i][j]][map[i][j]]++;
					a[map[i][j]][map[tx][ty]]--;
				}
			}
		}
	}
	printf("%lld\n",guass());
	return 0;
}
posted @ 2019-03-12 21:11  dreagonm  阅读(103)  评论(0编辑  收藏  举报