「学习笔记」Matrix-Tree 定理

Matrix-Tree 定理

行列式

定义

对于一个 \(N\times N\) 的矩阵 \(A\),其行列式为

\[\det(A)=\sum_{P}(-1)^{\mu(P)}\prod A_{i,P_i} \]

其中 \(P\)\(N\) 的排列,\(\mu(P)\)\(P\) 的逆序对个数。

也就是在每一行挑一个数,不在同一列,将它们乘起来,系数与逆序对个数有关。

性质

  • 交换矩阵的两行,行列式变号

  • 将矩阵的某一行乘 \(t\),行列式也乘 \(t\)

  • \(\begin{vmatrix}a+a'&b+b'\\c&d\end{vmatrix}=\begin{vmatrix}a&b\\c&d\end{vmatrix}+\begin{vmatrix}a'&b'\\c&d\end{vmatrix}\)

  • 如果有某两行一样的矩阵,行列式为 \(0\) (考虑交换它们)

  • 用矩阵的一行假声另一行的倍数,行列式不变

  • 矩阵的行列式等于消元后上三角矩阵中对角线上的乘积

代码

int det(int n)
{
    int res = 1;
    for(int i = 1; i <= n; i++)
    {
        for(int j = i + 1; !a[i][i] && j <= n; j++)
            if(a[j][i]) swap(a[i], a[j]), res = mod - res;
        int inv = qpow(a[i][i], mod - 2);
        for(int j = i + 1; j <= n; j++)
            for(int k = n; k >= 1; k--)
                a[j][k] = (a[j][k] - 1ll * a[i][k] * a[j][i] % mod * inv % mod + mod) % mod;
        res = 1ll * res * a[i][i] % mod;
    }
    return res;
}

矩阵树定理

求图的生成树个数

无向图

\(D\) 为度数矩阵,\(G\) 为邻接矩阵

则基尔霍夫矩阵 \(K=D-G\)

然后令 \(K'\)\(K\) 去掉任意一行一列的矩阵

\(\det(K')\) 即为生成树的个数

有向图

若求外向树个数,那么 \(D\) 为入度矩阵,否则,\(D\) 为出度矩阵。

注意是有向图,所以会固定一个根,在求行列式时,如果去掉第 \(k\) 行第 \(k\) 列,那么值为指定 \(k\) 为根的生成树个数。

加权

可以理解为有重边的情况,将边权看成重复的边数,再求生成树个数即可。

例题

有向图+无向图:Luogu P6178 【模板】Matrix-Tree 定理

无向图:Luogu P4336 [SHOI2016]黑暗前的幻想乡

有向图:Luogu P4455 [CQOI2018]社交网络

加权:Luogu P3317 [SDOI2014]重建

posted @ 2021-12-20 15:45  Acestar  阅读(256)  评论(0编辑  收藏  举报