矩阵树定理与BEST定理
行列式#
定义:
1. 对于一个上三角矩阵,他的行列式等于主对角线所有值的乘积。
要使
以此类推,使
2. 单位矩阵的行列式为
根据
3. 交换矩阵两行,行列式变号。
交换
4. 将矩阵某行乘上一个常数,行列式乘上相同常数。
不妨将第
5. 若矩阵有相同的两行,则行列式为
交换两行会使行列式变号,但是矩阵没变,即
6. 若矩阵有两行存在倍数关系,则行列式为
7. 若两个矩阵至多有一行不等,将这不等的一行相加得到的新矩阵的行列式等于原行列式之和。
设不等的行编号为
8. 将矩阵的某行加上另一行的倍数,行列式不变。
设把
设
高斯消元#
步骤略。
题意:求一个
将
有恒等式
矩阵可逆当且仅当
题意:给定一个
把
加上某一行的倍数不改变答案,而交换两行会使符号改变,因此记录交换了多少次。
没有必要对一行乘某个常数的操作,否则还有额外记录乘了多少东西。
#include<bits/stdc++.h>
#define eb emplace_back
#define ep emplace
using namespace std;
using ll = long long;
int n, p, sgn; ll a[605][605];
int main() {
cin.tie(0)->sync_with_stdio(0);
cin >> n >> p;
for(int i = 1; i <= n; ++ i) {
for(int j = 1; j <= n; ++ j) {
cin >> a[i][j];
a[i][j] %= p;
}
}
for(int k = 1; k <= n; ++ k) {
for(int i = k; i <= n; ++ i) {
if(a[i][k]) {
if(i != k) {
swap(a[i], a[k]), sgn ^= 1;
}
break;
}
}
if(!a[k][k]) return cout << 0, 0;
for(int i = k + 1; i <= n; ++ i) {
while(a[i][k]) {
if(a[i][k] < a[k][k]) {
swap(a[i], a[k]), sgn ^= 1;
}
ll q = a[i][k] / a[k][k];
for(int j = k; j <= n; ++ j) {
a[i][j] = (a[i][j] + p - q * a[k][j] % p) % p;
}
}
}
}
ll tmp = 1;
for(int i = 1; i <= n; ++ i) tmp = tmp * a[i][i] % p;
cout << (sgn ? (p - tmp) % p : tmp);
return 0;
}
矩阵树定理#
无向图生成树个数
设
设
定义拉普拉斯矩阵:
记图
其中记号
无向图拉普拉斯矩阵所有
有向图生成树个数
定义出度矩阵
设
定义出度拉普拉斯矩阵
同理定义入度矩阵
记以
记以
边权积的和
对于一条
BEST定理#
设
欧拉图任意节点为根的外向树数量相等,且所有节点出度和入度相等(这也说明
注意:BEST定理只能在欧拉图上使用。
P5807 【模板】BEST 定理 | Which Dreamed It
题意:求从
对于一条欧拉回路,保留除
此时图中一定无环。
这样除了
我们钦定一棵内向树,然后对于其他边任意定顺序,一定唯一对应一个欧拉回路。
充分性有了,考虑必要性,显然每一个欧拉回路都唯一对应一颗内向树和其中遍历出边的顺序。
因此总方案就是
由此可以引出BEST定理,统计整张图本质相同的欧拉回路个数(循环同构)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通