zoukankan      html  css  js  c++  java
  • bzoj 4031: 小Z的房间 矩阵树定理

    bzoj 4031: 小Z的房间 矩阵树定理

    题目:

    你突然有了一个大房子,房子里面有一些房间。事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子。在一开始的时候,相邻的格子之间都有墙隔着。
    你想要打通一些相邻房间的墙,使得所有房间能够互相到达。在此过程中,你不能把房子给打穿,或者打通柱子(以及柱子旁边的墙)。同时,你不希望在房子中有小偷的时候会很难抓,所以你希望任意两个房间之间都只有一条通路。现在,你希望统计一共有多少种可行的方案。
    n,m <= 9

    题解:

    矩阵树板子题.
    刚学的矩阵树定理,练练手.

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    inline void read(int &x){
        x=0;static char ch;bool flag = false;
        while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
        while(x=(x<<1)+(x<<3)+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    #define rg register int
    #define rep(i,a,b) for(rg i=(a);i<=(b);++i)
    #define per(i,a,b) for(rg i=(a);i>=(b);--i)
    const int maxn = 128;
    const int mod = 1e9;
    char s[maxn][maxn];
    int id[maxn][maxn],nodecnt;
    int a[maxn][maxn];
    inline int det(int n){
        int ret = 1,s=0;
        rep(i,1,n){
            rg r = i;
            for(r=i;r <= n;++r) if(a[r][i] != 0) break;
                if(r == n+1) return 0;
            if(r != i){
                s ^= 1;
                rep(j,i,n) swap(a[r][j],a[i][j]);
            }
            rep(j,i+1,n){
                while(a[j][i]){
                    int x = a[j][i]/a[i][i];
                    rep(k,i,n){
                        a[j][k] -= 1LL*a[i][k]*x % mod;
                        if(a[j][k] < 0) a[j][k] += mod;
                    }
                    if(a[j][i] == 0) break;
                    s ^= 1;
                    rep(k,i,n) swap(a[j][k],a[i][k]);
                }
            }
            ret = 1LL*ret*a[i][i] % mod;
        }
        if(s) ret = mod - ret;
        return ret;
    }
    int main(){
        int n,m;read(n);read(m);
        rg u,v;
        rep(i,1,n){
            scanf("%s",s[i]+1);
            rep(j,1,m){
                if(s[i][j] == '*') continue;
                id[i][j] = ++ nodecnt;
                u = id[i][j];
                    if(s[i-1][j] == '.'){
                    v = id[i-1][j];
                    ++ a[u][u]; ++ a[v][v];
                    -- a[u][v]; -- a[v][u];
                }
                if(s[i][j-1] == '.'){
                    v = id[i][j-1];
                    ++ a[u][u]; ++ a[v][v];
                    -- a[u][v]; -- a[v][u];
                }
            }
        }
        int lim = nodecnt;
        rep(i,1,n*m) rep(j,1,lim){
            if(a[i][j] >= mod) a[i][j] -= mod;
            if(a[i][j] < 0) a[i][j] += mod;
        }
        printf("%d
    ",det(lim-1));
        return 0;
    }
    
  • 相关阅读:
    C#操作XML配置文件
    Git详细命令
    ng : File C:UsersaronAppDataRoaming pm g.ps1 cannot be loaded because running
    Abstract抽象类 && Interface接口
    Markdown基本使用
    Scrapy基本使用
    request取值相关
    轮询与长轮询
    爬虫
    Flask相关组件及应用
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6713222.html
Copyright © 2011-2022 走看看