BZOJ 4031 小Z的房間 (矩陣樹定理)
阿新 • • 發佈:2019-01-02
題意:
計算給定圖的生成樹的個數
分析:
矩陣樹定理板題。
#include<bits/stdc++.h> using namespace std; int z[11][11]; int a[90][90]; char s[11][11]; const int mod=1e9; int n,m,S; int gs(){ S--; for(int i=1;i<=S;i++){ for(int j=1;j<=S;j++){ a[i][j]=(a[i][j]+mod)%mod; } } 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]%mod+mod)%mod; swap(a[i][k],a[j][k]); } ans*=-1; } } if(a[j][j]==0) return 0; ans=ans*a[j][j]%mod; } return (ans+mod)%mod; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%s",s[i]+1); } for(int i=0;i<=n+1;i++){ for(int j=0;j<=m+1;j++){ if(i==0||j==0||i==n+1||j==m+1){ s[i][j]='*'; } } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(s[i][j]=='.'){ z[i][j]=++S; if(s[i-1][j]=='.'){ a[z[i-1][j]][z[i][j]]=1; a[z[i][j]][z[i-1][j]]=1; } if(s[i][j-1]=='.'){ a[z[i][j-1]][z[i][j]]=1; a[z[i][j]][z[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][j]=-a[i][j]; a[i][i]++; } } } printf("%d\n",gs()); return 0; }