Loading

【笔记】矩阵树定理

来自\(\texttt{SharpnessV}\)省选复习计划中的矩阵树定理


对于本节内容可以只记结论。


矩阵树定理用于解决一类生成树计数问题。

前置知识:高斯消元

例题1

高斯消元模板。对于一个 \(N\) 行,\(N+1\) 列的矩阵,先消成一个上三角矩阵,然后通过回代解除每个未知数的解。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define pre(i,a,b) for(int i=a;i>=b;i--)
#define N 105
using namespace std;
int n;double a[N][N];
void solve(){
	rep(i,1,n){
		double cur=a[i][i];
		if(!a[i][i]){puts("No Solution");return;}
		rep(j,i,n+1)a[i][j]/=cur;
		rep(j,i+1,n)pre(k,n+1,i)a[j][k]-=a[j][i]*a[i][k];
	}
	pre(i,n,1)rep(j,1,i-1)a[j][n+1]-=a[j][i]*a[i][n+1];
	rep(i,1,n)printf("%.2lf\n",a[i][n+1]);
}
int main(){
	scanf("%d",&n);
	rep(i,1,n)rep(j,1,n+1)scanf("%lf",&a[i][j]);
	solve();
	return 0;
} 

例题2

行列式求值模板。

一个 \(n\)\(n\) 列的矩阵,它行列式的值为 \(\large\sum\limits_{p}(-1)^{\tau(p)}\prod \limits_{i=1}^{n}a_{i,p_i}\)

性质 \(1\) ,上三角矩阵的行列式为对角线上元素乘积。

根据定义

性质 \(2\) ,交换两行,答案变为原来的相反数

交换后\(\prod\)中的内容不变,变的是\(\tau(p)\),可以手算证明交换一个排列的两个元素后逆序对的奇偶性相反。

性质 \(3\) ,两行相等,行列式为 \(0\)

交换两行都答案为相反数,同时原矩阵没有改变,答案不变,所以只能为 \(0\)

性质 \(4\) ,一行乘 \(k\) ,行列式乘 \(k\)

根据定义

性质 \(5\) ,一行加上另一行的 \(k\) 倍,答案不变。

\(\large\sum\limits_{p}(-1)^{\tau(p)}\prod \limits_{i=1}^{n}(a_{i,p_i}+\Delta_i)=\large\sum\limits_{p}(-1)^{\tau(p)}\prod \limits_{i=1}^{n}a_{i,p_i}+\large\sum\limits_{p}(-1)^{\tau(p)}\Delta\prod \limits_{i=1\land \Delta_i\neq 0}^{n}a_{i,p_i}\)

我们发现这是两个行列式的值,其中第二个行列式的值根据性质 \(3\)\(0\),所以答案不变

我们发现上面 \(5\) 个性质正好对应高斯消元的几个操作,我们直接将行列式消成上三角矩阵然后求值即可。

为避免除法,我们可以通过辗转相除法,经过势能分析时间复杂度仍然是 \(\rm O(N^3)\) 的。

代码


例题3

矩阵树定理模板。

矩阵树定理:一个图生成树数量为其 Kirchhoff 矩阵去除第 \(k\) 行和第 \(k\) 列后的行列式的值,\(k\)任意。

证明略

定义:Kirchhoff 矩阵为度数矩阵减去邻接矩阵,\(a_{i,i}\)表示节点 \(i\) 的度数,\(a_{i,j}\)表示\(i\to j\)是否有边。

扩展 \(1\) :最后求出的行列式值为 \(\sum\limits_{tree}\prod\limits_{e_i\in tree}w_{e_i}\)

\(w_e=1\)时,值恰好为生成树数量。

扩展 \(2\) :Kirchhoff 矩阵删去第 \(k\) 行和列后算出的答案为根为第 \(k\) 个节点的生成树数量。虽然在无向图中没有区别。

扩展 \(3\) :计算有向图生成树时,度数矩阵是节点\(i\)的入度时,计算的是外向树的数量,否则计算的是内向树的数量。

根据扩展 \(3\) : 我们不难推导得到,计算有向图生成树时,将矩阵沿\(y=x\)对角线翻转并不会影响答案。

最后求行列式即可算出答案。

代码


例题4

推导一下发现我们需要求的是\(\large\prod\limits_{e}(1-p_e)\sum\limits_{tree}\prod\limits_{e_i\in tree}\dfrac{p_e}{1-pe}\)

前面是一个常量,后面是矩阵树定理应用的标准形式。

代码


例题5

容斥原理和矩阵树定理的结合。值得一做的好题,难度不大。

代码


例题6

\(2020\)年联合省选题,不会矩阵树会吃大亏。

需要技巧的一道题。

首先通过反演\(\varphi *1=\rm Id\) 消去 \(\gcd\)

然后得到\(\sum\limits_{tree}\sum\limits_{e_i\in tree}w_{e_i}\)形式的求值。

我们发现这不是我们标准形式的求值,考虑将加法变为乘法。

如果做过类似题目不难知道,我们用二项式乘法代替常数项加法,最后二项式系数即为加法和。

注意一下这里涉及多项式除法,不能辗转相除,必须写高斯消元的标准形式。

代码


例题7

求与给定树相交恰好 \(k\) 条边的生成树个数。

我们将给定树的边权置为单项式 \(x\) ,其余的边置为常数 \(1\)

我们发现如果一个生成树的边权之积为 \(x^k\),则恰好与原树相交 \(k\) 条边。

于是我们可以通过矩阵树定理求出所有生成树边权乘积之和,\(x^k\)项的系数即为答案。

直接多项式乘法复杂度过高,由于答案是一个\(n-1\)次多项式,所以我们可以带入\(n\)个常数然后插值求出原多项式。

代码

posted @ 2022-04-14 09:56  7KByte  阅读(216)  评论(0编辑  收藏  举报