zoukankan      html  css  js  c++  java
  • 【BZOJ4031】【Luogu P4111】[HEOI2015]小Z的房间

    裸的矩阵树定理。求行列式的时候答案要在中间统计,因为交换两个行会使答案取反。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 10 + 5;
    const int M = 100 + 5;
    const int mod = 1000000000;
    
    char s[N][N];
    
    int n, m, a[M][M], id[N][N];
    
    void add (int u, int v) {
        --a[u][v], --a[v][u], ++a[u][u], ++a[v][v];
    }
    
    int Gauss (int n) {
        int ans = 1;
        for (int i = 1; i <= n; ++i) {
            for (int k = i + 1; k <= n; ++k) {
                while (a[k][i]) {
                    int d = a[i][i] / a[k][i];
                    for (int j = i; j <= n; ++j) {
    					a[i][j] = (((a[i][j] - 1LL * d * a[k][j]) %mod) + mod) %mod;
    				}
                    swap (a[i], a[k]), ans =- ans;
                }
            }
            ans = (((1LL * ans * a[i][i]) % mod) + mod) % mod;
        }
        return ans;
    }
    
    int main () {
    	cin >> n >> m;
        for (int i = 1; i <= n; ++i) cin >> s[i] + 1;
        int idx = 0;
        for (int i = 1; i <= n; ++i) {
    		for (int j = 1; j <= m; ++j) {
    			if (s[i][j] == '.') {
    				id[i][j] = ++idx;
    			}
    		}
    	}
        for (int i = 1; i <= n; ++i) {
    		for (int j = 1; j <= m; ++j) {
    			if (s[i][j] == '.') {
    		        if(id[i - 1][j]) add (id[i][j], id[i - 1][j]);
    		        if(id[i][j - 1]) add (id[i][j], id[i][j - 1]);
        		}
    		}
    		 
    	}
        cout << Gauss (idx - 1) << endl;
        return 0;
    }
    
  • 相关阅读:
    《信息学奥赛一本通》提高版题解索引
    QUERY [ 单调栈 ]
    [ 模拟退火 ] bzoj3860 平衡点
    [ 考试 ] 7.12
    离线和简单分治
    [ 校内OJ ] NOIP2019模拟赛(九)
    校内模拟考 (一)
    Codeforces 808E
    学习笔记—点分治
    [ 线段树+哈希 ] 反等差数列
  • 原文地址:https://www.cnblogs.com/maomao9173/p/10943938.html
Copyright © 2011-2022 走看看