zoukankan      html  css  js  c++  java
  • 矩阵树(Matrix-Tree)定理精华

    前言

    证明不重要,结论直接背

    普通矩阵树定理

    一张无边权的无向图生成树个数为其基尔霍夫矩阵去掉某一行与相应列的行列式 (允许重边)

    基尔霍夫矩阵: 度数矩阵(仅主对角线有值,值为该点度数的矩阵) - 邻接矩阵

    有边权

    用于统计无向图生成树的权值和 (生成树的权值为其边权乘积)

    将边权作为同等数量的边加入基尔霍夫矩阵即可

    有向边+指定根

    外向树: 加正边入邻接矩阵,统计入度

    内向边: 加反边入邻接矩阵,统计出度

    指定根: 删除基尔霍夫矩阵中指定根节点对应的行和列即可

    代码

    struct matrix{
        int a[_][_],n;
        friend matrix operator -(matrix x,matrix y){ //矩阵减法
            matrix c;
            c.n=x.n;
            for(re int i=1;i<=c.n;i++)
                for(re int j=1;j<=c.n;j++) c.a[i][j]=(x.a[i][j]-y.a[i][j]+mod)%mod;
            return c;
        }
        ll det()//行列式
        {
            ll ans=1, ff=1;
            for(re int j=1;j<=n;++j)
            {
                for(re int i=j;i<=n;++i)
                    if(a[i][j]) {
                        if(i!=j){swap(a[i],a[j]); ff+=ff*(-2);}
                        break;
                    }
                if(a[j][j]==0) return 0;
                ans=ans*a[j][j]%mod;
                ll inv=qpow(a[j][j],mod-2);
                for(re int i=j;i<=n;i++) a[j][i]=a[j][i]*inv%mod;
                for(re int i=j+1;i<=n;i++)
                {
                    int t=a[i][j];
                    for(re int k=j;k<=n;++k)
                        a[i][k]=(a[i][k]-a[j][k]*t%mod+mod)%mod;
                }
            }
            return ans*ff;
        }
        void SWAP(int k) //将第k行k列换到第n行n列(删除时直接n--,即可)
        {
            swap(a[k],a[n]);
            for(re int i=1;i<=n;i++) swap(a[i][k],a[i][n]);
        }
    }A;
    

    还有一种整数专用的辗转相除求行列式的办法
    (用于处理模数为非质数时的询问)

    struct matrix{
        int n,a[_][_];
        in ll det()
        {
            ll ans=1, ff=1;
            for(re int i=1;i<=n;++i)
                for(re int j=i+1;j<=n;++j)
                {
                    while(a[i][i])
                    {
                        int div=a[j][i]/a[i][i];
                        for(re int k=i;k<=n;++k) a[j][k]=(a[j][k]-a[i][k]*div%mod+mod)%mod;
                        swap(a[j],a[i]); ff=-ff;
                    }
                    swap(a[j],a[i]); ff=-ff;
                }
            for(re int i=1;i<=n;++i) ans=ans*a[i][i]%mod;
            return (ans*ff+mod)%mod;
        }
    }a;
    
    
    嗯,就这样了...
  • 相关阅读:
    数据库表结构查询SQL
    Java实现数据库备份并利用ant导入SQL脚本
    生死看淡,不服就干。SQL常见的一些优化。
    mybatis + PageHelper 实现分页
    自定义数据库连接池实现方式 MySQL
    Docker 镜像基础(三)
    Docker 镜像管理及基础命令(二)
    Docker 介绍和安装(一)
    Docker 镜像管理及基础命令(二)
    Tomcat-8 安装和配置
  • 原文地址:https://www.cnblogs.com/yzhx/p/14560429.html
Copyright © 2011-2022 走看看