「学习笔记」Matrix-Tree 定理
Matrix-Tree 定理
行列式
定义
对于一个 \(N\times N\) 的矩阵 \(A\),其行列式为
\[\det(A)=\sum_{P}(-1)^{\mu(P)}\prod A_{i,P_i}
\]
其中 \(P\) 为 \(N\) 的排列,\(\mu(P)\) 为 \(P\) 的逆序对个数。
也就是在每一行挑一个数,不在同一列,将它们乘起来,系数与逆序对个数有关。
性质
-
交换矩阵的两行,行列式变号
-
将矩阵的某一行乘 \(t\),行列式也乘 \(t\)
-
\(\begin{vmatrix}a+a'&b+b'\\c&d\end{vmatrix}=\begin{vmatrix}a&b\\c&d\end{vmatrix}+\begin{vmatrix}a'&b'\\c&d\end{vmatrix}\)
-
如果有某两行一样的矩阵,行列式为 \(0\) (考虑交换它们)
-
用矩阵的一行假声另一行的倍数,行列式不变
-
矩阵的行列式等于消元后上三角矩阵中对角线上的乘积
代码
int det(int n)
{
int res = 1;
for(int i = 1; i <= n; i++)
{
for(int j = i + 1; !a[i][i] && j <= n; j++)
if(a[j][i]) swap(a[i], a[j]), res = mod - res;
int inv = qpow(a[i][i], mod - 2);
for(int j = i + 1; j <= n; j++)
for(int k = n; k >= 1; k--)
a[j][k] = (a[j][k] - 1ll * a[i][k] * a[j][i] % mod * inv % mod + mod) % mod;
res = 1ll * res * a[i][i] % mod;
}
return res;
}
矩阵树定理
求图的生成树个数
无向图
\(D\) 为度数矩阵,\(G\) 为邻接矩阵
则基尔霍夫矩阵 \(K=D-G\)
然后令 \(K'\) 为 \(K\) 去掉任意一行一列的矩阵
\(\det(K')\) 即为生成树的个数
有向图
若求外向树个数,那么 \(D\) 为入度矩阵,否则,\(D\) 为出度矩阵。
注意是有向图,所以会固定一个根,在求行列式时,如果去掉第 \(k\) 行第 \(k\) 列,那么值为指定 \(k\) 为根的生成树个数。
加权
可以理解为有重边的情况,将边权看成重复的边数,再求生成树个数即可。
例题
有向图+无向图:Luogu P6178 【模板】Matrix-Tree 定理
无向图:Luogu P4336 [SHOI2016]黑暗前的幻想乡
$$A\ drop\ of\ tear\ blurs\ memories\ of\ the\ past.$$