矩阵树定理学习笔记
行列式基础:
约定:
表示排列 的逆序对数量
引理:
引理1:对换(交换排列中任意两个元素)改变 奇偶性:
考虑一次临项交换必定会使得逆序对数量
引理2:行列交换,行列式值不变。
每一行只选一个,因此是对称的。
引理3:单位矩阵 的行列式的值为
除了对角线的排列,没得选。
类似的,上三角矩阵的行列式的值为
引理3:交换两行,行列式变号。
只考虑这两行,相当于对每个排列在这两行做一次对换,奇偶性改变,因此行列式的值会变号。
引理4:给某一行 ,行列式
这个是比较显然的,每一行只选一个,因此可以给他提出来这个
引理5:行具有线性性
两个矩阵只有一行不一样,两个矩阵这一行对应相加之后的行列式的值=两个矩阵行列式的值相加。
还是每一行只选一个,因此对于某行中选了某个数的,给他展开之后就行了。
引理6:有两行一样的矩阵,行列式为
根据引理3,交换两行符号取反,但是矩阵没有边,相当于
引理7:用矩阵的一行加上另一行的倍数,行列式不变。
假设是第
给第
然后根据引理5,两个矩阵第
一个是零,一个是原矩阵,发现行列式的值就是原矩阵的。
高斯消元求行列式:
高斯消元其实只需要交换行,一行加上另一行的倍数,记录交换次数即可。
注意为了避免实数预算,使用辗转相减法做高斯消元,模板:
点击查看代码
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;
}
注意:对于一些有规律的行列式,可以考虑展开后求递推式。
定义去掉某些行列的剩余部分行列式为余子式,然后代数余子式就是乘上
设删掉
那么就有
通过这个可以降阶。
更一般的表述是下面的定理:
拉普拉斯展开定理:在
阶行列式中,任意取定 行,由 行元素组成的所有 阶子式与代数余子式乘积之和等于行列式的值。
矩阵树定理(Matrix-Tree theorem)
矩阵树定理指出了一下事实:
定义 Kirchhoff 矩阵为:
其中
记
则
其中删掉的行列是作为跟
应用
无向图生成树:
无论是求数量还是边权的乘积,都只用维护出
直接把无向边视为有向边,分别贡献
有向图生成树
- 内向树:
表示边 对 的贡献(出度) - 外向树:
表示边 对 的贡献(入度)
为啥是这样呢,考虑从删掉的一行一列考虑, 内向树跟没有出度,因此删掉他,统计他人的出度,外向树跟没有入度,统计他人入度。
例题与扩展:
相当于统计每个恰好
然后就是矩阵树定理模板了。
注意不选的边不选也是有概率的,不止和选了的边有关系。
考虑形式化列出要求的东西:
矩阵树定理能求的只能和选了的有关系,不选的部分我们用所有的除以选了的来处理(最关键点)
变成:
化简:
对于
最小生成树经典结论:
- 对于不同的最小生成树,边权相同的边总是数量相同的。
- 对于不同权值的边,互不影响,也就是加入每种权值得边贡献的连通性相同。
根据 Envy 的套路,想到了一个看起来很对的假做法:预处理出所有可能在最小生成树中边,然后直接跑矩阵树定理。
其实是错误的,因为这样对导致不同权值之间的边相互影响,使得某种边权的边贡献的连通性超过或不足自己本来应该贡献的。
hack数据:
点击查看代码
4
1 2 1
3 4 1
1 4 2
2 3 2
如果直接预处理,有可能连出两个
那怎么办呢:注意到每种边权的边贡献的连通性确定,也就是加入其他边权的任意树边后形成的连通块上,这种边权的边在做任意生成树,此时可以用矩阵树定理求出方案数。
由于不同权值的边互不影响,因此可以直接乘起来。
复杂度:设每种边权在
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】