BZOJ4031小Z的房间

矩阵树定理的应用

具体矩阵树定理的性质参考本文

//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int mo=1000000000;
int n,m,S;
int s[11][11];
char z[11][11];
int a[82][82];
int gs()
{
    S--;
    long long ans=1;
    for(int j=1;j<=S;j++)
    {	
        for(int i=j+1;i<=S;i++)
            while(a[i][j])
            {
              	long long t=a[j][j]/a[i][j];
               	for(int k=j;k<=S;k++)
                   	a[j][k]=(a[j][k]-t*a[i][k]%mo+mo)%mo,
                   		swap(a[i][k],a[j][k]);
               	ans*=-1;
            }
        ans=ans*a[j][j]%mo;
       }
    return (ans+mo)%mo;
}//懵逼的高斯消元
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%s",z[i]+1);
    for (int i=0;i<=m+1;i++) z[0][i]='*';
    for (int i=0;i<=m+1;i++) z[n+1][i]='*';
    for (int i=0;i<=n+1;i++) z[i][0]='*';
    for (int i=0;i<=n+1;i++) z[m+1][0]='*';
    //圈起来
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(z[i][j]=='.')
            {
               s[i][j]=++S;
               if(z[i-1][j]=='.') a[s[i-1][j]][s[i][j]]=1;
               if(z[i-1][j]=='.') a[s[i][j]][s[i-1][j]]=1;
               if(z[i][j-1]=='.') a[s[i][j-1]][s[i][j]]=1;
               if(z[i][j-1]=='.') a[s[i][j]][s[i][j-1]]=1;
            }
     //根据关系构建两个矩阵
     for(int i=1;i<=S;i++)
        for(int j=1;j<=S;j++)
            if(a[i][j]&&i!=j)
            	a[i][i]++;
    printf("%d",gs());
    return 0;
}


猜你喜欢

转载自blog.csdn.net/acerandaker/article/details/80877304