zoukankan      html  css  js  c++  java
  • BZOJ 4031: [HEOI2015]小Z的房间(Matrix Tree)

    传送门

    解题思路

      矩阵树定理模板题。矩阵树定理是求图中最小生成树个数,做法是首先求出基尔霍夫矩阵,就是度数矩阵(-)邻接矩阵。然后再求出这个矩阵的行列式,行列式的求法就是任意去掉一行一列,然后高斯消元消成上三角,对角线乘积即为行列式。注意到这里有取模,所以要辗转相除。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define int long long
    typedef long long LL;
    
    using namespace std;
    const int MAXN = 11;
    const int MAXM = MAXN*MAXN;
    const int MOD = 1e9;
    
    int n,m,tot,Mp[MAXN][MAXN],f[MAXM][MAXM],ans=1;
    char s[MAXN][MAXN];
    
    inline void add(int x,int y){
    	f[x][x]++;f[y][y]++;f[x][y]--;f[y][x]--;
    }
    
    inline void Matrix_Tree(){
    	int t;
    	for(int i=1;i<tot;i++){
    		for(int j=i+1;j<tot;j++)
    			while(f[j][i]){
    				t=f[i][i]/f[j][i];
    				for(int k=i;k<tot;k++)
    					f[i][k]=(f[i][k]-t*f[j][k]%MOD+MOD)%MOD;
    				swap(f[i],f[j]);ans=-ans;
    			}
    		ans=ans*f[i][i]%MOD;
    	}
    	ans=(ans+MOD)%MOD;
    }
    
    signed main(){
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=n;i++) {
    		scanf("%s",s[i]+1);
    		for(int j=1;j<=m;j++)
    			if(s[i][j]=='.') Mp[i][j]=++tot;	
    	}
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++) if(s[i][j]=='.'){
    			if(Mp[i-1][j]) add(Mp[i][j],Mp[i-1][j]);
    			if(Mp[i][j-1]) add(Mp[i][j],Mp[i][j-1]);
    		}
    	Matrix_Tree();printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    java 键盘监听事件
    DOM扩展
    DOM
    CSS hack
    客户端检测
    BOM
    函数表达式
    面向对象的程序设计
    引用类型(下)
    引用类型(上)
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10044592.html
Copyright © 2011-2022 走看看