版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sunshiness_s/article/details/81406946
题解
连一些边,然后矩阵树定理就可以了
但是注意这里的模数不是质数!
因此不能用逆元啥的,需要辗转相除!!!
代码
#include <cstdio>
#include <algorithm>
using namespace std;
#define ll long long
#define N 90
#define mod 1000000000
char str[N];
int n,m,num,a[N][N],id[10][10];
inline void insert(int x,int y){
a[x][x]++;a[y][y]++;
a[x][y]--;a[y][x]--;
}
inline void gauss(){
ll ans=1;--num;
for(int i=1;i<=num;i++){
int r=i;
while(r<=num&& !a[r][i]) r++;
if(r>num){puts("0");return ;}
if(r!=i){
ans*=-1;
for(int j=i;j<=num;j++) swap(a[r][j],a[i][j]);
}
for(int j=i+1;j<=num;j++){
while(a[j][i]){
ll t=a[j][i]/a[i][i];
for(int k=i;k<=num;k++) a[j][k]=(a[j][k]-(ll)t*a[i][k]%mod+mod)%mod;
if(!a[j][i]) break;
ans*=-1;
for(int k=i;k<=num;k++) swap(a[j][k],a[i][k]);
}
}
}
for(int i=1;i<=num;i++) ans=ans*a[i][i]%mod;
printf("%lld\n",(ans+mod)%mod);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",str+1);
for(int j=1;j<=m;j++){
if(str[j]=='.'){
id[i][j]=++num;
if(id[i-1][j]) insert(id[i-1][j],id[i][j]);
if(id[i][j-1]) insert(id[i][j-1],id[i][j]);
}
}
}
gauss();
return 0;
}