Kruskal算法
按边权排序,从小到大合并不在同一集合两点即可
Prim算法
每次加入一个到当前已选点集最近的点
考虑二分,每次给白边加上一个mid,通过这种方式来改变选择白边个数,注意要正好取need个,注意边界细节 代码
有向图的最小树形图,考虑到这道题的高度性质,直接把边按照和高度为第一关键字,边权为第二关键字排序kruskal即可 代码
如果这条边能在最小生成树中,那么意味着用权值小于L的边无法把u和v合并到同一集合,所以把小于L的边权设为1,然后从u到v求最小割即可 最大生成树同理 代码
非严格次小生成树
对于每条未被选中的边,(u,v,w)找u到v的路径中边权最大的一个,用w替换这条边。求路径u到v的最大值时,可以利用倍增
严格次小生成树
考虑上述非严格的原因是可能w等于路径上的最大值,所以我们用倍增维护一个严格次大值,这样当w和路径最大值相等时,我们用严格次大值来计算即可
矩阵树定理
1.无向图
度数矩阵:对角线上为度数值,其余位置均为0
邻接矩阵:i-j之间的边数
基尔霍夫矩阵=度数矩阵-邻接矩阵
基尔霍夫矩阵的任意一个n-1阶主子式的行列式就是最小生成树个数
直接考虑每个公司都得负责一个较为困难,观察到n较小,可以使用容斥计算,f(st)表示提供公司集合为st的最小生成树数量(不考虑是否每个选一个)。那么答案就是所有都选了的生成树个数−1个没选的+2个没选的−…
代码 这个高斯消元用了逆元计算
把每个边不选的概率提出来,再把每条边的边权改成选的概率/不选的概率即可
2.有向图
入度拉普拉斯矩阵=入度矩阵-邻接矩阵
出度拉普拉斯矩阵=出度矩阵-邻接矩阵
入度拉普拉斯矩阵去掉根节点的一行一列,行列式就是叶向树的方案数
出度拉普拉斯矩阵去掉根节点的一行一列,行列式就是根向树的方案数
有向图模板
LGV引理
这道题目由于a和b都是递增的,所以排列方式只有一种
E((ai,1),(bj,n))=C(n-1-ai+bj,n-1)
两两之间的矩阵相乘,最后求行列式的值就是答案
具体的证明方式和LGV有关 代码
Prufer序列
将一个代标号的n个节点的树,映射成一个n-2个[1,n]的整数序列
构造方式:每次选择编号最小的叶子节点删除,在序列中记录下连接它的那个节点,用一个指针扫一下就可以线性构造了 代码
同样可以线性重构出树的形态
一些性质:
- 一个prufer序列对应一个有标号树
- 一个点在prufer序列中出现的次数为度数-1
- 一个n个点的完全图有棵生成树
给定每个点度数 可能方案为 代码
类似的 代码