实用算法 004: 矩阵树(Matrix Tree)和其扩展
矩阵树可以计算一个无向图的生成树个数或有向图的根向生成树和叶向生成树的个数。
由于有向图不怎么用到,下面只讨论无向图的情况。
注意:无向图可以存在重边,但不能存在自环
在下面的内容中默认N是点数,M是边数
定义1. 邻接矩阵 M M M,其中 M i , j M_{i,j} Mi,j表示 i , j i,j i,j之间的边数。可以发现 M M M是一个对称且对角线是 0 0 0的 N N N阶矩阵。
定义2. 度数矩阵 D D D,其中 D i , i D_{i,i} Di,i表示 i i i的度数,若 i ≠ j i\neq j i=j则 D i , j = 0 D_{i,j}=0 Di,j=0。
定义3. 拉普拉斯矩阵(Laplacian matrix) L = D − M L=D-M L=D−M
其中一个无向图的生成树个数 = det L 0 =\det L_{0} =detL0 (其中 L 0 L_0 L0表示去掉 L L L的第 i i i列和第 i i i行得到的矩阵, i i i任意),证明知乎的文章里有。
则对于一个图,算出生成树个数的时间复杂度为 O ( N 3 ) O(N^3) O(N3),主要是高斯消元算行列式的复杂度。
扩展
如果无向图的边有边权,然后可以令 M i , j M_{i,j} Mi,j表示 i , j i,j i,j之间边的边权(没有边则为0)。
然后
det
L
0
\det L_0
detL0就是=
∑
T
∏
e
i
∈
T
w
i
\sum_{T} \prod_{{e_i}\in T} w_i
T∑ei∈T∏wi
也就是所有生成树边的乘积的和。
p r o o f : proof: proof:
将权值理解成边数,也就是 i , j i,j i,j之间有了 M i , j M_{i,j} Mi,j条边。
特殊的: 边权不要求是数,甚至可以是多项式(如例题)
例题:
这题是要求算出与原树有恰好 k k k条边重合的方案数。
我们可以构建一张图,图中边权定义如下,边权为多项式。
-
若边 i , j i,j i,j是原树中的边,则边权为 x 1 x^1 x1。
-
否则为 x 0 x^0 x0
然后通过矩阵树定理,算出的 det L 0 \det L_0 detL0也是一个多项式。
则和原树有恰好k条边重合的方案数即为 x k x^k xk的系数。
但是这样直接套ntt,时间复杂度为 O ( n 4 log n ) O(n^4\log n) O(n4logn),优化方法见:003