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

    P4111 [HEOI2015]小Z的房间

    矩阵树定理 高斯消元

    矩阵树定理:一个图的(度数矩阵-邻接矩阵)的行列式的值是图中所有生成树的方案数

    求行列式:把行列式去掉任意一行一列,转成上三角矩阵,矩阵对角线上元素之积即为行列式的值

    于是我们可以用高斯消元把另一半消掉,因为模数并不是质数,所以用辗转相除法。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int mod=1e9;
    char q[12];
    int n,m,cnt;
    long long ans=1,d[102][102];
    bool b[12][12],w[102];
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i){
            scanf("%s",q);
            for(int j=1;j<=m;++j) b[i][j]= q[j-1]=='.' ? 1:0;
        }
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j){
                int _it=(i-1)*m+j; //二维坐标映射成编号
                if(!b[i][j]) {w[_it]=1; continue;} 
                if(b[i-1][j]) --d[_it][_it-m],++d[_it][_it];
                if(b[i][j-1]) --d[_it][_it-1],++d[_it][_it];
                if(b[i+1][j]) --d[_it][_it+m],++d[_it][_it];
                if(b[i][j+1]) --d[_it][_it+1],++d[_it][_it];
            } //度数矩阵-邻接矩阵
        cnt=n*m-1; //默认去掉最后一行和最后一列
        for(int i=1;i<=cnt;++i){
            if(w[i]) continue; //是墙就跳过
            for(int j=i+1;j<=cnt;++j){
                if(w[j]) continue;
                while(d[j][i]){ //辗转相除法高斯消元
                    int t=d[i][i]/d[j][i];
                    for(int k=i;k<=cnt;++k) d[i][k]=(d[i][k]-t*d[j][k]+mod)%mod;
                    swap(d[i],d[j]),ans=(mod-ans)%mod;
                }
            }
            ans=(ans*d[i][i]+mod)%mod; //对角线之积
        }
        printf("%lld",(ans+mod)%mod);
        return 0;
    }
  • 相关阅读:
    android基本架构
    c#编辑框只接受数字
    listbox数据源绑定问题
    QQ在线客服代码
    用VB生成DLL封装ASP代码例子
    C#,关于DataGridView的一些方法
    转:ASP.NET中引用dll“找不到指定模块"的完美解决办法
    编译asp.net文件为dll文件
    好看的表格样式
    网站IIS日志解读
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9665259.html
Copyright © 2011-2022 走看看