行列式 / 矩阵树定理 / BEST 定理 笔记
一、行列式
对于一个
其中
定理 1
对于一个右上三角矩阵
证明:考虑构造使得乘积不为
的排列 ,第 行只能选择 ,即 ,第 行只能选择 ,其中 已被选择,故 ,可以得到 ,此时 中没有逆序对。
定理 2
交换
证明:原操作相当于交换
,考虑 中逆序对个数的变化。分类讨论可以证明变化总是奇数,故 的指数奇偶改变,取反。
定理 3
将某行的每一个数乘上一个数
证明:因为每一行只取一个数,故在每次乘积上都乘了个
。
定理 4
有两行相同的矩阵,
证明:由定理 2,交换这两行,
取反,但是交换前后矩阵一致,故 。
定理 5
证明:乘法分配律
定理 6
证明:
。
实现
根据定理 1 & 6,使用高斯消元 / 辗转相除法,即可求出行列式。
点击查看代码(高斯消元)
bool op = false;
for (int i = 1; i < n; i++) {
for (int j = i; j < n; j++)
if (a[j][i]) {
if (j != i)
op ^= 1;
swap(a[i], a[j]);
break;
}
if (!a[i][i]) {
cout << 0;
return 0;
}
ans = ans * a[i][i] % mod;
for (int j = i + 1; j < n; j++) {
int x = a[j][i] * inv(a[i][i]) % mod;
for (int k = i; k < n; k++)
a[j][k] = (a[j][k] - a[i][k] * x % mod + mod) % mod;
}
}
cout << (op ? (mod - ans) % mod : ans);点击查看代码(辗转相除法)
bool op = false;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
while (a[i][i]) {
int div = a[j][i] / a[i][i];
for (int k = i; k <= n; k++)
a[j][k] = (a[j][k] - div * a[i][k] % mod + mod) % mod;
swap(a[i], a[j]);
op ^= 1;
}
swap(a[i], a[j]);
op ^= 1;
}
ans = ans * a[i][i] % mod;
}
cout << (op ? (mod - ans) % mod : ans);二、余子式
注意本节符号与其它节的不同。
定义
假设
令
与主子式的关系
选定一个
选定一个
太菜了,不会证明啊。
三、矩阵树定理
1. 无向图无权情况
定义
定义
2. 有向图外向树
外向树,即从根指向四周。
定义
删去
3. 有向图内向树
内向树,即从四周指向根。
定义
4. 重边情况
将“是否有边”改成“边的个数即可”。
5. 刷题总结
(1). P6178 【模板】Matrix-Tree 定理
生成树的权值是边权的乘积,其意义就是在一条边有边权种选择,本质就是重边。
(2). P4208 [JSOI2008] 最小生成树计数
将边权
将连通块缩点后,对
(3). P2144 [FJOI2007] 轮状病毒
裸的矩阵树定理就能做,但是
分析一下矩阵
那矩阵树定理做
设
可是
选定第一行做行列式向代数余子式的转换。
删除
则得到
这回右边的矩阵很有规律了,记
删除
则得到
考虑再对这个矩阵的第一列做转化,当选中
删除
同上,选中第一列做转化,当选中
终于,我们得到了
接着考虑求
用复杂的线性代数知识就可以得到
四、BEST 定理
对于一个有向图的欧拉回路,将除了起点
假如走出了环,回路最后一定要回到
起点有
其中
若无规定起点,则要除去循环同构的部分。