Matrix Tree Theorem & LGV Lemma & Best Theorem
三个定理都和行列式有关系,放在一起看联系。
行列式基础:
约定:
- \(\tau(P)\) 表示排列 \(P\) 的逆序对数量
- \(det(A)=\sum\limits_{P}(-1)^{\tau(P)}\prod\limits_{i}^{n}A_{i,p_i}\)
引理:
引理1:对换(交换排列中任意两个元素)改变 \(\tau(P)\) 奇偶性:
考虑一次临项交换必定会使得逆序对数量 \(+-1\),一定会改变奇偶性。兑换 \((i,j),i<j\) 可以看成将 \(p_i\) 向右进行 \(i-j\) 次临项交换,将 \(a_j\) 向左进行 \(i-j-1\) 此临项交换。共进行了 \(2\times(i-j)-1\) 次,因此一定会改变排列逆序对数量的奇偶性。
引理2:行列交换,行列式值不变。
每一行只选一个,因此是对称的。
引理3:单位矩阵 \(I\) 的行列式的值为 \(1\)
除了对角线的排列,没得选。
类似的,上三角矩阵的行列式的值为 \(\prod\limits_{i=1}^{n}a_{i,i}\)。
引理3:交换两行,行列式变号。
只考虑这两行,相当于对每个排列在这两行做一次对换,奇偶性改变,因此行列式的值会变号。
引理4:给某一行 \(\times t\),行列式 \(\times t\)
这个是比较显然的,每一行只选一个,因此可以给他提出来这个 \(t\)。
引理5:行具有线性性
两个矩阵只有一行不一样,两个矩阵这一行对应相加之后的行列式的值=两个矩阵行列式的值相加。
还是每一行只选一个,因此对于某行中选了某个数的,给他展开之后就行了。
引理6:有两行一样的矩阵,行列式为 \(0\)
根据引理3,交换两行符号取反,但是矩阵没有边,相当于 \(det(A)=-det(A)\),即 \(det(A)=0\)。
引理7:用矩阵的一行加上另一行的倍数,行列式不变。
假设是第 \(i\) 行加到第 \(j\) 行,构造一个第 \(j\) 行和第 \(i\) 行都是原矩阵中第 \(i\) 行的矩阵。根据引理6,这个矩阵的行列式为 \(0\)。
给第 \(j\) 行 \(\times k\),根据引理4,矩阵的行列式仍为 \(0\)。
然后根据引理5,两个矩阵第 \(j\) 行对应相加之后的行列式等于之前两个行列式的值相加。
一个是零,一个是原矩阵,发现行列式的值就是原矩阵的。
高斯消元求行列式:
高斯消元其实只需要交换行,一行加上另一行的倍数,记录交换次数即可。
注意为了避免实数预算,使用辗转相减法做高斯消元,模板:
点击查看代码
int Gauss()
{
int ans=1;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
while(a[j][i]!=0)
{
int d=a[i][i]/a[j][i];
for(int k=i;k<=n && d;k++) a[i][k]=(a[i][k]-a[j][k]*d%mod+mod)%mod;
swap(a[i],a[j]),ans=-ans;
}
}
}
for(int i=1;i<=n;i++) ans=ans*a[i][i]%mod;
return (ans+mod)%mod;
}
注意:对于一些有规律的行列式,可以考虑展开后求递推式。
定义去掉某些行列的剩余部分行列式为余子式,然后代数余子式就是乘上 \((-1)^{sumrem_i+sumrem_j}=(-1)^{sumdel_i+sumdel_j}\)
设删掉 \(i,j\) 的余子式称为 \(M_{i,j}\);
那么就有 \(D=\sum\limits_{j=1}^{m}(-1)^{i+j}M_{i,j} \times a_{i,j}\)。
通过这个可以降阶。
更一般的表述是下面的定理:
拉普拉斯展开定理:在 \(n\) 阶行列式中,任意取定 \(k\) 行,由 \(k\) 行元素组成的所有 \(k\) 阶子式与代数余子式乘积之和等于行列式的值。
\(a_{i,j}\) 相当于为子式,\(M_{i,j} \times (-1)^{i+j}\) 相当于代数余子式。
矩阵树定理(Matrix-Tree Theorem)
结论:
矩阵树定理指出了一下事实:
定义 Kirchhoff(Laplace) 矩阵为:
\( K_{i,j}= \left\{ \begin{aligned} \sum\limits_{k!=i} w(i,k) & & i=j \\ -w(i,j)& & i!=j \\ \end{aligned} \right. \)
其中 \(w(i,j)\) 表示边 \((i,j)\) 对 \(i\) 的影响(边的方向视情况而定)
记 \(M\) 为 \(K\) 删掉任意编号相同的行列后的矩阵 (\(n-1\) 阶子矩阵)
则有:
容易发现当权值都为 \(1\) 的时候,统计的是有根生成树的方案数,记作 \(T(G,k)\),表示图 \(G\) 以 \(k\) 为根的生成树个数。
其中删掉的行列是作为跟
应用
无向图生成树:
无论是求数量还是边权的乘积,都只用维护出 \(w\) 矩阵即可。
直接把无向边视为有向边,分别贡献 \(w()\) 即可。
有向图生成树
- 内向树:\(w(i,j)\) 表示边 \(i\rightarrow j\) 对 \(i\) 的贡献(出度)
- 外向树:\(w(i,j)\) 表示边 \(i \leftarrow j\) 对 \(i\) 的贡献(入度)
为啥是这样呢,考虑从删掉的一行一列考虑, 内向树跟没有出度,因此删掉他,统计他人的出度,外向树跟没有入度,统计他人入度。
例题与扩展:
相当于统计每个恰好 \(0\) 人不参与的方案数,经典套路容斥,转化为钦定 \(i\) 人不参与,其余任意的方案数。
然后就是矩阵树定理模板了。
注意不选的边不选也是有概率的,不止和选了的边有关系。
考虑形式化列出要求的东西:
矩阵树定理能求的只能和选了的有关系,不选的部分我们用所有的除以选了的来处理(最关键点)
变成:
化简:
对于 \(0,1\) 用 \(eps\) 扰动一下即可。
最小生成树经典结论:
- 对于不同的最小生成树,边权相同的边总是数量相同的。
- 对于不同权值的边,互不影响,也就是加入每种权值得边贡献的连通性相同。
根据 Envy 的套路,想到了一个看起来很对的假做法:预处理出所有可能在最小生成树中边,然后直接跑矩阵树定理。
其实是错误的,因为这样对导致不同权值之间的边相互影响,使得某种边权的边贡献的连通性超过或不足自己本来应该贡献的。
hack数据:
点击查看代码
4
1 2 1
3 4 1
1 4 2
2 3 2
如果直接预处理,有可能连出两个 \(2\) 边权的生成树。
那怎么办呢:注意到每种边权的边贡献的连通性确定,也就是加入其他边权的任意树边后形成的连通块上,这种边权的边在做任意生成树,此时可以用矩阵树定理求出方案数。
由于不同权值的边互不影响,因此可以直接乘起来。
复杂度:设每种边权在 \(k\) 个联通块上做生成树,则总复杂度为 \(\sum\limits_{k} k^3 < n^3 (\sum\limits_{k} = n-1)\)
边权的改造:
将边权设定为多项式/生成函数,可以多加一维限制,同时可以处理的信息更为广泛。
回忆二项式定理的部分:\((x+y)^k=\sum\limits_{i=0}^{k}\binom{k}{i}x_iy_{k-i}\)。
卷积带组合数,考虑用 EGF 消掉,\(F_w(x)=\sum\limits_{i \ge 0}\frac{w^i x^i}{i!}\),这样就是直接卷积(多项式乘法),比较方便。
这样最终的答案就应该是 \(k![x^k] Det(M)\)。
注意,选主元的时候,不能选常数项为 \(0\) 的。
- 例2:用集合幂级数描述边权
把边权用集合幂级数描述,设 \(f_w=x^w\),这样在位运算下做乘法,最终的 \([x^n]\) 就是位运算权值为 \(n\) 的方案数。
\(\operatorname{FWT}\) 做完后是是点积,分开做就好了。
LGV 引理(LGV Lemma)
人话描述,证明省略。
定义与约定:
-
给定 \(n\) 个起点 \(\{a_i\}\) 和终点 \(\{b_i\}\),以及一张包含这些点的 DAG,保证起点无入度,终点无出度。
-
定义一条路径 \(P\) 的权值是经过所有边边权的乘积:\(W(P)=\prod\limits_{e \in P} w_e\)。
-
定义在排列上的路径 \(P_i\) 为 \(\{P_i: a_i \rightarrow b_{p_i},p \in S_n\}\),
其中 \(p\) 是这个路径组的排列,也就是起点对应的终点是谁。
-
定义一个路径组 \(P: \{P_i, p \in S_n\, i=\{1,2,3,…,n\}\}\)
如果这个路径组中不存在任何一个结点 \(u\),使得存在 \(i,j,i \not =j,u \in P_i,u \in P_j\),则称这个路径组为无交路径组,记为 \(P'\)。
路径组的权值为所有路径权值的乘积:\(W(P)=\prod\limits_{i=1}^{n}W(P_i)\)
-
构造矩阵 \(A \in \mathbb{Z}^{n \times n}\),其中 \(A_{i,j}=W(a_i,b_j)\),
其中 \(W(a_i,b_j)\) 就是从 \(a_i\) 到 \(b_j\) 的所有路径 \(P\) 的权值和:\(\sum W(P)\)。
结论:
应用:
对于应用场景的要求:
-
必须在 DAG 上;
-
一般会要求所有路径无交。
对于最终结论的应用一般有两种:
-
直接和你说是逆序对数量偶减奇的方案数;
-
合法的不交路径唯一(没有逆序对),则此时路径的数量(权值)就是行列式的值。
对于细节分析和具体做法,确定 LGV 引理的三个要素:起点集合,终点集合,矩阵权值。
一般情况下要么在起点终点集合上做手脚,要么要求你快速算矩阵权值。
或者直接对着行列式的式子做排列的状压 Dp。
例题:
-
CF348D Turtles
需要你自己确定一下起点和终点 -
[NOI2021] 路径交点
需要思考正负号和逆序对的关系 -
[ABC216H] Random Robots
没有终点怎么办
Best 定理 (Best Theorem)
直接上,没有废话,不证明了。
无向图欧拉回路计数不可做,不要再往这个方面想了。
如果是无向图尝试定向。
结论:
欧拉回路:
无向图 \(G\) 的欧拉回路数量为(同构的算一个,无起点):
\(T(G,k)\) 就是矩阵数定理里面描述的那个,现在具体指的是以 \(k\) 为根的内向生成树的个数。
注意在欧拉回路中有:$\forall u,v\in [1,n], T(G,u)=T(G,v) $。
如果算以 \(u\) 为起点的,则需要再乘上一个 \(deg_u\),表示枚举第一条出边。
你可以理解为,先选定一个起点,然后将整个回路分成了 \(deg\) 段,如果无起点相当于环排列数量,有起点相当于排列数量。
欧拉路径
后来发现欧拉路径也是可以的,其实很多次用了就是总结一一下:
欧拉路径的判定是(不含回路),有且仅有一个起点 \(S\) 和终点 \(T\),就是入度和出度不相等的那两个点。
先把他变成欧拉回路,连一条 \(T \rightarrow S\) 的边,此时对于矩阵树的那个基尔霍夫矩阵影响是:\(K_{T,S}-1,K_{T,T}+1\)。
但是如果我们算以 \(T\) 为根的内向树个数,这个是不受影响的。
算剩余部分的时候,注意到这个 \(T\) 的出度加了 \(1\),而且我们算的是以他为起点的,因此他的系数是 \((d_{T}+1)!\),但是我们还要求这个新连的边必须是第一条,因此还要除上 \(d_{T}+1\).
这样最终欧拉回路的数量就是:
应用:
应用场景:
必须是欧拉回路(路径)才行,然后记得去掉孤立点,即在矩阵中删掉一行一列即可。
欧拉回路的判定:所有点入度等于出度,并且所有非零度点强连通。
应用方法:
最主要的就是建模出来有向欧拉回路模型。答案是在计数方案,没啥难的,比前两个建模简单很多。
很多时候经过点的限制要拆到边上刻画。
例题:
-
【模板】BEST 定理 | Which Dreamed It
练习 check 方法。
-
无向图,咋办?定向!
-
[USACO21OPEN] Routing Schemes P
不知道为啥模板能评黑。
-
欧拉路径计数
-
连续段 dp 好题。但是用 Best定理好像更奇妙。

浙公网安备 33010602011771号