【BZOJ 4031】: [HEOI2015]小Z的房间
题目大意:
给一个n×m的网格,“.”表示可联通,求该网格可构成的生成树个数在1E9的剩余系中的结果。(n,m<=9)
题解:
忘了删注释WA了两遍……
直接建图+MartrixTree定理即可。
代码:
1 #include "bits/stdc++.h" 2 3 using namespace std; 4 5 typedef long long ll; 6 7 const int N=500; 8 9 ll a[N][N]; 10 11 int n,mod=1e9; 12 13 inline ll det(){ 14 ll res=1; 15 for(int i=0;i<n;++i){ 16 if(!a[i][i]){ 17 bool flag=false; 18 for(int j=i+1;j<n;++j){ 19 if(a[j][i]){ 20 flag=true; 21 for(int k=i;k<n;++k) swap(a[i][k],a[j][k]); 22 res=-res; 23 break; 24 } 25 } 26 if(!flag) return 0; 27 } 28 for(int j=i+1;j<n;++j){ 29 while(a[j][i]){ 30 ll t=a[i][i]/a[j][i]; 31 for(int k=i;k<n;++k){ 32 a[i][k]=(a[i][k]-t*a[j][k])%mod; 33 swap(a[i][k],a[j][k]); 34 } 35 res=-res; 36 } 37 } 38 res*=a[i][i]; 39 res%=mod; 40 } 41 if(res<0) res+=mod; 42 return res; 43 } 44 45 int main(){ 46 int r,c; 47 scanf("%d%d",&r,&c); 48 char mp[11][11]; 49 int s[11][11],xx[4]={0,0,-1,1}, 50 yy[4]={1,-1,0,0}; 51 memset(s,-1,sizeof(s)); 52 for(int i=1;i<=r;++i) 53 scanf("%s",mp[i]+1); 54 for(int i=1;i<=r;++i) 55 for(int j=1;j<=c;++j) if(mp[i][j]=='.') 56 s[i][j]=n++; 57 for(int i=1;i<=r;++i) 58 for(int j=1;j<=c;++j) if(s[i][j]!=-1) 59 for(int k=0;k<4;++k){ 60 int x=i+xx[k],y=j+yy[k]; 61 if(x>0&&y>0&&x<=r&&y<=c){ 62 if(s[x][y]!=-1){ 63 x=s[x][y],y=s[i][j]; 64 a[x][y]=-1,a[y][x]=-1; 65 ++a[y][y]; 66 } 67 68 } 69 } 70 --n; 71 printf("%lld\n",det()); 72 }
没有什么不可能。