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;
}