[BZOJ 4031] 小Z的房间
Link:
Solution:
矩阵树定理的模板题
看完下面两篇文章就会啦:
周冬论文:https://wenku.baidu.com/view/872eb02de2bd960590c677c6.html
WerKeyTom_FTD的严谨证明%%%:https://blog.csdn.net/WerKeyTom_FTD/article/details/54914530
Code:
//by NewErA #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll MOD=1e9; const int MAXN=15*15; char dat[MAXN][MAXN]; ll pos[MAXN][MAXN],a[MAXN][MAXN],n,m,cnt=0; int dx[]={1,-1,0,0}; int dy[]={0,0,1,-1}; ll det(ll x) { for(int i=1;i<=x;i++) for(int j=1;j<=x;j++) a[i][j]=(a[i][j]+MOD)%MOD; ll ret=1,f=1; for(int i=1;i<=x;i++) { for(int j=i+1;j<=x;j++) { ll A=a[i][i],B=a[j][i]; while(B!=0) { ll t=A/B;A%=B;swap(A,B); for(int k=i;k<=x;k++) a[i][k]=(a[i][k]-t*a[j][k]%MOD+MOD)%MOD; for(int k=i;k<=x;k++) swap(a[i][k],a[j][k]); f=-f; } } if(!a[i][i]) return 0; ret=ret*a[i][i]%MOD; } if(f==-1) return (-ret+MOD)%MOD; else return ret%MOD; } int main() { cin >> n >> m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin >> dat[i][j]; if(dat[i][j]=='.') pos[i][j]=++cnt; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(dat[i][j]=='.') { for(int k=0;k<4;k++) { int fx=i+dx[k],fy=j+dy[k]; if(fx<1 || fx>n || fy<1 || fy>m || dat[fx][fy]!='.') continue; a[pos[i][j]][pos[i][j]]++; a[pos[i][j]][pos[fx][fy]]--; } } cout << det(cnt-1); return 0; }