矩阵树定理
矩阵树定理,又称 Matrix-Tree 定理,是用于解决图上生成树问题的有力工具。其基础是基于线性代数中的矩阵和行列式进行计算。
1 基本定义
1.1 图的关联矩阵
我们先来研究无向图的情况。设一张无向图 \(G=(V,E)\),\(|V|=n,|E|=m\),我们给每一条边随意定一个方向,然后定义该图的关联矩阵 \(M\) 为:
显然该矩阵大小为 \(n\times m\)。
1.2 拉普拉斯矩阵
定义一张图的拉普拉斯矩阵(又称基尔霍夫矩阵)\(L_{i,j}\) 为:
其中 \(\text{deg}(v)\) 表示顶点度数,\(\text{cnt}(i,j)\) 表示两点间连边数量(不分方向)。
关于这两个矩阵有一个非常实用的性质:\(L=MM^T\),证明如下:
- \(L_{i,i}=\sum\limits_{j=1}^m M_{i,j}M_{j,i}^{T}=\sum\limits_{j=1}^mM_{i,j}^2=\text{deg}(i)\)。
- \(L_{i,j}=\sum\limits_{k=1}^m M_{i,k}M_{k,j}^{T}=\sum\limits_{j=1}^mM_{i,k}M_{j,k}=-\text{cnt}(i,j)\)。
这将会在下文中用到。
2 基本理论
在正式讲解矩阵树定理前,我们需要说明两个基本理论。
2.1 用关联矩阵刻画生成树
我们最后要求出一棵生成树,相当于在关联矩阵中选出 \(n-1\) 列。设这些列编号集合为 \(S\),记只保留这些列的矩阵为 \(M[S]\)。此时其大小为 \(n\times(n-1)\),不是很美观。考虑把其中任意一行去掉,这样做的含义实际上是忽略生成树的根,因为无向图生成树不需要管根,所以矩阵依然对应唯一的生成树。记去掉任意一行后的矩阵为 \(M_0\),则最后生成树对应的矩阵是 \(M_0[S]\)。
考虑此时矩阵 \(M_0[S]\) 要满足什么条件。显然如果生成的树不合法则说明出现了环,而环上的边对应的列向量必然线性相关,那么也就是说 \(M_0[S]\) 不满秩,也就是 \(\text{det}(M_0[S])=0\);反之,我们考虑消元法计算行列式值,每次找出叶子节点所在行,此时这一行上只有一个非零元素,利用该行进行消元,然后删去叶子节点递归进行该过程,最后每一行上都只剩下一个非零元素,所以 \(\text{det}(M_0[S])=\pm 1\)。
2.2 柯西-比内定理
柯西-比内定理,又称 Cauchy-Binet 定理,是用于计算两矩阵相乘后行列式结果的定理。令 \(A\) 为 \(n\times m\) 的矩阵,\(B\) 为 \(m\times n\) 的矩阵,则:
3 矩阵树定理
3.1 无向图上的情况
3.1.1 定理内容
记 \(L_0\) 为 \(L\) 去掉任意的第 \(k\) 行和第 \(k\) 列所得到的矩阵,则该无向图生成树个数为 \(\det(L_0)\)。
3.1.2 定理证明
利用上面讲解的基本理论,这个定理的证明其实很简单:
此时 \(S\) 对应一种选边方案,根据上面的说明,只有在该选边方案合法时 \(\det(M_0[S])=\pm 1\),那么 \(\det(M_0[S])^2=1\),也就算出了生成树的个数。
3.2 有向图上的情况
3.2.1 定理内容
对于有向图,我们的生成树实际上有两种:根向生成树和叶向生成树。这里只讨论叶向生成树的方案数,另一种是类似的。
重新定义拉普拉斯矩阵为:
其中 \(\text{deg}_{\text{in}}(v)\) 表示顶点入度,\(\text{cnt}(i\to j)\) 表示 \(i\) 到 \(j\) 边的个数。
那么此时有向图上的矩阵树定理和无向图基本一致,记 \(L_0\) 为 \(L\) 去掉任意的第 \(k\) 行和第 \(k\) 列所得到的矩阵,则以 \(k\) 为根的叶向生成树个数为 \(\det(L_0)\)。
3.2.2 定理证明
此时我们没有 \(L=MM^T\) 了,所以我们需要换一种方法证明。
依然先考虑对 \(M_0[S]\) 消元求行列式,同样从叶子节点开始消元,此时叶子节点对应行上只有一个元素是 \(1\),并且这一列上也只有另一个元素是 \(-1\),所以消完之后每一行会正好剩一个 \(1\),也就是 \(\det(M_0[S])=1\)。
但是此时我们只保证了生成出来的是一棵树,并没有保证它是叶向树,考虑用另一个 \(D\) 矩阵强制确定一下,叶向树的另一个条件是除根以外每一个节点都只有一条入边,所以假如我们可以让 \(\det(D_0[S])=1\) 等价于这个条件,就可以满足外向树限制。事实上这也是容易构造的,有:
那么此时我们可以得到 \(L=MD^T\),然后再按照上面的证明方法证即可。
3.3 有边权的情况
有边权其实也比较简单,我们可以将边权 \(w\) 看成 \(w\) 条边,然后跑一下矩阵树。那么根据乘法原理,一棵生成树会被计算其边权的乘积次。所以对于有边权的图跑矩阵树定理,求出来的是所有生成树的边权乘积之和。
4 例题
使用矩阵树的时候常常有一个问题:题目要求边权和,但是矩阵树求的是边权乘积。对此我们也有一些常见的处理方式,下面两道题都会运用。
例 1 LOJ6271 「长乐集训 2017 Day10」生成树求和 加强版
首先我们看到要对生成树权值求和,自然想到利用矩阵树定理进行求解。但是矩阵树定理适用于求边权之积的和的情况,与此题并不是很适配。考虑先进行一些转化。
我们发现一棵树的权值就是三进制不进位加法,首先由于不进位我们可以把每一位拆开考虑;而不进位加法则容易让我们想到 \(k\) 维 FWT。在本题中显然 \(k=3\),套用 \(3\) 维 FWT 不进位加法的做法,矩阵是 \(\begin{bmatrix}1&1&1\\1&\omega_3^1&\omega_3^2\\1&\omega_3^2&\omega_3^4\end{bmatrix}\),对于 \(i=0,1,2\) 求出边权 FWT 后的结果,则乘积就是答案 FWT 后结果。如此树的权值就被转化为了乘积,可以直接利用矩阵树定理求解。最后我们对答案做一次 IFWT 即可得出每种权值的树有多少种,累加答案即可。复杂度 \(O(n^3\log_3 V)\)。
例 2 P6624 [省选联考 2020 A 卷] 作业题
首先看到题目中的 \(\gcd\),想到欧拉反演:
所以我们枚举一下 \(\gcd\),然后保留所有是 \(d\) 倍数的边,求出所有生成树边权和的和即可。这容易让我们联想到矩阵树定理,不过矩阵树定理求解的是生成树边权积之和,我们需要一些转化。最简单的想法是把边权放到指数上,构造 \(x^{w_i}\),不过这样的话难以操作且复杂度过高。我们采用另一种方法,把边权记为 \(w_ix+1\),这样我们只需要求出乘积的一次项系数就是边权和了。
那么这样的话我们做乘除法操作的时候就不用管二次项了,于是有如下运算规则:
- \((a+bx)(c+dx)=ac+(bc+ad)x\)。
- \(\dfrac{1}{a+bx}=\dfrac{b}{a}-\dfrac{b}{a^2} x\)。
构造出矩阵后直接高斯消元求解行列式即可,复杂度是 \(O(n^3 V)\) 的。直接跑比较紧张,我们可以用一点优化,显然只有 \(d\) 的倍数出现了至少 \(n-1\) 次时我们才需要求解,那么总的因子个数是 \(\sum \sigma_0(w_i)\),所以我们至多跑 \(\tfrac{\sum \sigma_0(w_i)}{n-1}\) 次,复杂度应该是 \(O(n^2\sum \sigma_0(w_i))\) 的,上界是一个 \(O(n^4\sqrt V)\),可以通过。

浙公网安备 33010602011771号