矩阵树定理
矩阵树定理解决了一张图的生成树个数计数问题。
本篇记号声明
本篇中的图,无论无向还是有向,都允许重边,但是默认没有自环。
有自环的情形
自环并不影响生成树的个数,也不影响下文中 Laplace 矩阵的计算,故而矩阵树定理对有自环的情形依然成立。计算时不必删去自环。如果删去自环,会影响根据 BEST 定理应用矩阵树定理统计有向图的欧拉回路个数。
无向图情况
设
设
定义 Laplace 矩阵(亦称 Kirchhoff 矩阵)
记图
有向图情况
设
类似地定义入度矩阵
设
定义出度 Laplace 矩阵
定义入度 Laplace 矩阵
记图
记图
定理叙述
矩阵树定理具有多种形式。
定义
定理 1(矩阵树定理,无向图,行列式形式)
对于无向图
也就是说,无向图的 Laplace 矩阵所有
推论 1(矩阵树定理,无向图,特征值形式)
设
定理 2(矩阵树定理,有向图根向树,行列式形式)
对于有向图
也就是说,有向图的出度 Laplace 矩阵删去第
因此如果要统计一张图所有的根向树形图,只要枚举所有的根
定理 3(矩阵树定理,有向图叶向树,行列式形式)
对于有向图
也就是说,有向图的入度 Laplace 矩阵删去第
因此如果要统计一张图所有的叶向树形图,只要枚举所有的根
注
根向树形图也被称为内向树形图,但因为计算内向树形图用的是出度,为了不引起
定理证明
观察上述定理形式极为相似,这里给出一种统一的证明方式,并且将之前的结论拓展到带权的图上。
证明的大致思路如下:
- 首先,所有情形都可以转化为计数有向图上根向树形图的情形;
- 利用矩阵语言给出选出的若干边可以构成根向树形图的充要条件;
- 将选边的操作利用 Cauchy–Binet 公式和 Laplace 矩阵的行列式联系起来;
- 最后,将行列式形式的结论转化为特征值形式的结论。
引理:Cauchy–Binet 公式
引理 1(Cauchy–Binet)
给定
这里求和记号的含义是,
证明(组合视角)
参考 「NOI2021」路径交点 的模型,首先考虑行列式的如下组合意义。对于
其中,
在理解行列式的组合意义后,可以利用如下的组合模型证明 Cauchy–Binet 公式。对于
对于左侧,基于上面描述的图
对于右侧,它相当于枚举了所有可能的中间点的组合。给定任何中间点集合
证明(代数视角)
上述组合证明其实可以逐字逐句地翻译成代数证明。这里转而提供另一种技巧性较强的代数证明,但用到了几个常见结论。当
当
当
又已知结论,
这里,第二个等号用到了
用关联矩阵刻画图的结构
对于有向图
和
它们每行都记录了一条边:出度关联矩阵
简单计算可知
进而有
前文的 Cauchy–Binet 公式表明,Laplace 矩阵的主子式其实是一系列子结构的和。每个子结构都反映了对应的子图的性质。
引理 2
对于
不为零。而且,该式当不为零时,必然等于
证明
不妨设
首先分析两个因子等于零的条件。前一个因子
假定前一个因子不为零,则此时子图
综上所述,如果
带权有向图的矩阵树定理
现在可以证明本文的主要结果。前文所述矩阵树定理均为该定理的特殊情形。
定理 4(矩阵树定理,带权有向图根向树,行列式形式)
对于任意的
这里,
证明
记
遍历所有的
当
推论 4(矩阵树定理,带权无向图,行列式形式)
对于无向图
这里,
证明
对于无向图
此处用到了结论
特征值形式
仍然首先考虑有向图上的结论。
定理 5
对于有向图
这里,
就等于
证明
仿照定理 4 的证明,注意到如果令
遍历所有的
将
引理 3
Laplace 矩阵
证明
只要证明它的行列式为零即可。仿照定理 4 和 5 的证明,取
推论 5
对于有向图
证明
对所有可能的
定义
推论 6
记无向图
这里,
证明
仿照推论 4 的证明,可以直接利用推论 5 的结论。有向图中每一个由
应用
Cayley 公式
推论 7(Cayley)
大小为
证明
等价地,只要求得
计算它的任意主子式,有
应用定理 1 即得到结论。
BEST 定理
前置知识:欧拉图
这一定理将有向欧拉图中欧拉回路的数目和该图的根向树形图的数目联系起来,从而解决了有向图中的欧拉回路的计数问题。注意,任意无向图中的欧拉回路的计数问题是 NP 完全的。
在实现该算法时,应当首先判定给定图是否是欧拉图,移除所有零度顶点,然后建图计算根向树形图的个数,并由 BEST 定理得到欧拉回路的计数。注意,如果所求欧拉回路个数要求以给定点作为起点,需要将答案再乘上该点出度,相当于枚举回路中首条边。
在证明 BEST 定理之前,需要知道如下结论。
性质(有向图具有欧拉回路的判定)
一个有向图具有欧拉回路,当且仅当非零度顶点是强连通的,且所有顶点的出度和入度相等。
对于欧拉图,因为出度和入度相等,可以将它们略去上标,记作
定理 6(BEST 定理)
设
这也说明,对欧拉图
证明
证明的大致思路是建立以
这一计数的组合含义对应的构造如下。对于起点为
- 一个以
为根的根向树形图,由所有非根顶点处的最后一条出边组成,即 , - 根
处所有出边的排列顺序,即 ,和 - 非根顶点
处除去最后一条出边之外的其他所有出边的排列顺序,即 。
下面说明,这样的构造得到的映射是双射。
一方面,给定欧拉回路,要证明所有非根顶点处的最后一条出边组成了一个根向树形图。根据构造,树中每个非根顶点的确只有一条出边,所以只需要证明这些出边不会成环。注意到,如果将所有顶点根据它在欧拉回路最后一次出现的顺序排序,那么非根顶点的最后一次出边必然指向顺序严格更靠后的顶点。如果存在环,那么环中就有一个顺序最靠后的顶点,因为它在环中,所以它指向了一个顺序并不靠后的点,这与上文矛盾。所以,非根顶点的最后一次出边必然构成根向树形图。
另一方面,给定任意根向树形图和其余出边的排列顺序,可以复原出一条欧拉回路,使得该欧拉回路经上述构造后可以得到给定的根向树形图和其余出边的排列顺序。对此,只需要从根
如果不能,则必然有某个顶点
可以验证这些映射都是单射,则必然同为双射。原命题得证。
实现
根据图写出 Laplace 矩阵,删去一行一列,求所得矩阵的行列式即可。求行列式可以使用 Gauss–Jordan 消元法。
例如,一个正方形图的生成树个数
可以用 Gauss–Jordan 消元解决,时间复杂度为
实现
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
constexpr int MOD = 100000007;
constexpr double eps = 1e-7;
struct matrix {
static constexpr int MAXN = 20;
int n, m;
double mat[MAXN][MAXN];
matrix() { memset(mat, 0, sizeof(mat)); }
void print() {
cout << "MATRIX " << n << " " << m << endl;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << mat[i][j] << "\t";
}
cout << endl;
}
}
void random(int n) {
this->n = n;
this->m = n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) mat[i][j] = rand() % 100;
}
void initSquare() {
this->n = 4;
this->m = 4;
memset(mat, 0, sizeof(mat));
mat[0][1] = mat[0][3] = 1;
mat[1][0] = mat[1][2] = 1;
mat[2][1] = mat[2][3] = 1;
mat[3][0] = mat[3][2] = 1;
mat[0][0] = mat[1][1] = mat[2][2] = mat[3][3] = -2;
this->n--; // 去一行
this->m--; // 去一列
}
double gauss() {
double ans = 1;
for (int i = 0; i < n; i++) {
int sid = -1;
for (int j = i; j < n; j++)
if (abs(mat[j][i]) > eps) {
sid = j;
break;
}
if (sid == -1) continue;
if (sid != i) {
for (int j = 0; j < n; j++) {
swap(mat[sid][j], mat[i][j]);
ans = -ans;
}
}
for (int j = i + 1; j < n; j++) {
double ratio = mat[j][i] / mat[i][i];
for (int k = 0; k < n; k++) {
mat[j][k] -= mat[i][k] * ratio;
}
}
}
for (int i = 0; i < n; i++) ans *= mat[i][i];
return abs(ans);
}
};
int main() {
srand(1);
matrix T;
// T.random(2);
T.initSquare();
T.print();
double ans = T.gauss();
T.print();
cout << ans << endl;
}
例题
例题 1:「HEOI2015」小 Z 的房间
解 矩阵树定理的裸题。将每个空房间看作一个结点,根据输入的信息建图,得到 Laplace 矩阵后,任意删掉
例题 2:「FJOI2007」轮状病毒
解 本题的解法很多,这里用矩阵树定理是最直接的解法。当输入为
求出它的
例题 2+
将例题 2 的数据加强,要求
解 推导递推式后利用矩阵快速幂即可求得。
推导递推式的过程:
注意到
的行列式。对
上述三个矩阵的行列式记为
注意到
将这些递推公式代入上式,得到:
于是猜测
改写成
例题 3:「BZOJ3659」WHICH DREAMED IT
解 本题是 BEST 定理的直接应用,但是要注意,由于题目规定「两种完成任务的方式算作不同当且仅当使用钥匙的顺序不同」,对每个欧拉回路,1 号房间可以沿着任意一条出边出发,从而答案还要乘以 1 号房间的出度。
例题 4:「联合省选 2020 A」作业题
解 首先需要用莫比乌斯反演转化成计算所有生成树的边权和,因为与本文关系不大所以略去。
将行列式的项写成
「北京省选集训 2019」生成树计数 是较为一般化的情况:计算生成树权值之和的
例题 5:AGC051D C4
解 无向图欧拉回路计数是 NPC 问题,但这题的图较为简单,确定了
创建日期: 2018年8月15日