[BZOJ 4031] 小Z的房间

Link:

BZOJ 4031 传送门

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;
}

 

posted @ 2018-06-05 22:18  NewErA  阅读(175)  评论(0编辑  收藏  举报