矩阵树定理

构建基尔霍夫矩阵,基尔霍夫矩阵的任意一个代数余子式是所有生成树的边权积的和,也就是求的是\(\sum\limits_T\prod\limits_{e\in T}v_e\)

无向图

基尔霍夫矩阵为度数矩阵减去邻接矩阵

任意去掉一行一列,所得到的矩阵的行列式即为所求

有向图

外向树为入度矩阵减去邻接矩阵

内向树出度矩阵减去邻接矩阵

删去根所在的行和列,所得到的矩阵的行列式即为所求

构建矩阵时,一条边对矩阵的贡献为其边权

行列式

转置矩阵,行列式不变

交换两行或两列的位置,行列式取相反数

对一行或一列乘以某数,行列式也乘以某数

用一行的倍数减去另一行,行列式的值不变

上三角矩阵的行列式的值等于对角线的乘积

利用这些性质将矩阵消为上三角矩阵后,即可求得行列式

\(code:\)

ll det()
{
    ll ans=1;
    for(int i=2;i<=n;++i)
    {
        for(int j=i+1;j<=n;++j)
        {
            while(a[j][i])
            {
                ll d=a[i][i]/a[j][i];
                for(int k=i;k<=n;++k)
                    a[i][k]=((a[i][k]-a[j][k]*d%mod)%mod+mod)%mod;
                swap(a[i],a[j]),ans*=-1;
            }
        }
        ans=ans*a[i][i]%mod;
    }
    return (ans%mod+mod)%mod;
}

double det()
{
    n--;
    double ans=1;
    for(int i=1;i<=n;++i)
    {
        int ma=i;
        for(int j=i+1;j<=n;++j)
            if(fabs(a[j][i])>fabs(a[ma][i]))
                ma=j;
        if(ma!=i) swap(a[ma],a[i]),ans*=-1;
        if(fabs(a[i][i])<eps) return 0;
        for(int j=i+1;j<=n;++j)
        {
            double d=a[j][i]/a[i][i];
            for(int k=i;k<=n;++k)
                a[j][k]-=a[i][k]*d;
        }
        ans*=a[i][i];
    }
    return ans;
}
posted @ 2020-03-20 23:42  lhm_liu  阅读(575)  评论(0编辑  收藏  举报