图论
图论
树
LCA
树链剖分,倍增
tarjan,欧拉序列转化为 RMQ 问题
树链剖分
重链,长链
树上启发式合并
重儿子的信息保留,轻儿子的暴力
虚树
把一棵树取出一部分节点建一棵虚树
- 将关键点按 DFS 序排序;
- 遍历一遍,任意两个相邻的关键点求一下 LCA,并且判重;
- 枚举相邻的两个点编号 x,y,求得它们的 lca 并且连接 lca,y
然后就建完了,节点数小于等于2k
树分治
点分治(淀粉质)
应该是解决树上的路径统计(点对...)等类型
直接从版题开始
题目大意是给定大小为n的树,给m个询问k,求树上是否有两点距离为k
首先点分治的本质:对于一个根节点,只有两种路径,过这个点的,和不过的
然后就先处理过这个点的,然后递归处理每个子树
这时注意,每次选树的重心,时间复杂度就可以达到稳定\(O(n\log n)\)
然后考虑本题,我们要做的就变成了过一个点的路径是否有距离为k(所以要注意判选的两个点不能再同个子树)
点分树
就是点分治后的树,满足深度小于等于logn
解法1
用时间复杂度为\(O(n\log^2n+nmlogn)\)的算法
首先扫出子树到该点的距离,理论上要算\(n\log n\)次(就是时间复杂度)
然后排序,对于每个k,两个指针l,r从两边扫,可以得出答案
解法2
用时间复杂度为\(O(n\log n+nmlogn)\)的算法
直接用桶记录,枚举m和子树大小
Kruskal 重构树
题前话:
瓶颈生成树=>最小生成树
最小瓶颈路=>在最小生成树上
次小生成树=>先最小生成树,再枚举非树边,在环上找最大值,mlogn
正题:
在跑 Kruskal 的过程中我们会从小到大加入若干条边,每次加边,新建一个节点,并把两个点的根作为其左右儿子,于是得到节点数2n-1,叶子数n,非叶子节点均有2个儿子
性质:原图中两个点之间的所有简单路径上最大边权的最小值 = 最小生成树上两个点之间的简单路径上的最大值 = Kruskal 重构树上两点之间的 LCA 的权值。
树分块
在树上随机撒\(\sqrt n\)个点,然后每个点向上跳到关键点或根的距离期望是\(\sqrt n\)
然后如果有需要建虚树,可以使得每个点都有前驱和后继
联通性
强连通分量
有向图中两两之间可以相互到达的点集
用tarjan找,若dfn[o]=low[o]就找到环,栈顶到o的点即为scc
缩点
把一个scc染成一个颜色
可以把有向图转为有向无环图,然后拓扑
双连通分量
边双:删去任意一边,图仍联通(有传递性)
点双:删去任意一点,图仍联通
用差分求一下
割点和桥
割点:删去该点后图不连通
桥:删去该边后图不连通
tarjan求一下
圆方树(广义圆方树)
圆方树是个好东西
顾名思义,就是一颗只有圆点(原点)和方点的树
建立它的方法就是将点双中的点全部连向一个方点,然后剪完图后把原边给删掉
然后就会有一些非常奇妙的性质:
- 每条边连接一个圆点和方点
- 建出来的图是棵树
然后还有一个点双很奇gay的性质
点双上任意两点的简单路径并等于点双的全集
设方点维护与之相邻的圆点权值,那么方点圆方树上
圆方树上任意两点的简单路径并等于路径上点双的全集,也就是路径上方点的贡献
然后它就非常适合解决简单路径的min,max之类的问题,直接树剖+线段树+lca
但是如果加入修改怎么办呢?暴力修改圆点相邻的方点可能是O(N^2)
然后就有个合理的设想,每个方点只维护它的儿子圆点,于是就只用修改圆点的父亲方点了
查询时就注意lca是方点要加上它父亲圆点的贡献
然后下面这道例题还要用multiset维护方点相邻圆点的权值,以保证方点的最小
哈密顿图
-
哈密顿通路:通过图中所有顶点一次且仅一次的通路。
-
哈密顿回路:通过图中所有顶点一次且仅一次的回路。
-
哈密顿图:具有哈密顿回路的图。
-
半哈密顿图:具有哈密顿通路而不具有哈密顿回路的图。
- 若图的最小度不小于顶点数的一半,则图是哈密顿图;
- 若图中每一对不相邻的顶点的度数之和不小于顶点数,则图是哈密顿图。
欧拉图
定义
-
欧拉回路:通过图中每条边恰好一次的回路
-
欧拉通路:通过图中每条边恰好一次的通路
-
欧拉图:具有欧拉回路的图
-
半欧拉图:具有欧拉通路但不具有欧拉回路的图欧拉图(欧拉通路&欧拉回路)
判定
1.对于无向图,所有边都是连通的
(1) 存在欧拉路径的充分必要条件: 度数为奇数的点只能是0或者2个(0个为欧拉回路的情况)
(2) 存在欧拉回路的充分必要条件: 度数为奇数的点只能有0个
2.对于有向图,所有边都是连通的
(1) 存在欧拉路径的充分必要条件: 要么所有点出度均等于入度(欧拉回路情况);要么除了两个点之外,其余点的出度等于入度,剩余的两个点:一个满足出度比入度多1(起点),另一个满足入度比出度多1(终点)
(2) 存在欧拉回路的充分必要条件: 所有点的出度均等于入度
性质
非形式化地讲,欧拉图就是从任意一个点开始都可以一笔画完整个图,半欧拉图必须从某个点开始才能一笔画完整个图。
欧拉图中所有顶点的度数都是偶数。
若\(G\)是欧拉图,则它为若干个环的并,且每条边被包含在奇数个环内。
寻找方法
1 记录点的情形
void dfs(int x)
对于从x出发的每条边(x, y)
如果该边没有被访问过
把这条边删去
dfs(y)
把x入栈
main()
dfs(1)
倒序输出栈中所有的节点
2 记录边的情形
void dfs(int x)
对于从x出发的每条边i(x, y)
如果该边没有被访问过
把这条边删去
dfs(y)
把边i入栈
main()
dfs(1)
倒序输出栈中所有的边
竞赛图
即有向完全图,满足一些有趣的性质
- 一定存在一条哈密顿通路
证明:考虑归纳法和反证法
首先n=1时成立,若n-1成立,一定有哈密顿通路,把它提出变成链
加入一个点n,那么链上每个点与n连一条边,若n->x则为1,若x->n则为0
若不存在哈密顿通路,则链头为0,链尾为1,且链上不能出现01(因为这样n可以加入链中),可以发现矛盾,证毕
- 每一个scc都为哈密顿图
证明:强连通的竞赛图是哈密顿图
- 缩点后是条链
证明:因为存在一条哈密顿路径,所以缩点一定是路径上连续的一段,因此缩完之后还是一条链。
- 若x的出度大于y,则x一定能走到y
证明:缩点后拓扑
若在一个scc中,一定成立
否则出度大的拓扑序一定小,再根据缩点后是条链,成立
兰道定理
将x->y视为x打赢y,那么竞赛图中点的出度即为比赛胜场,设为s
那么s序列合法的充要条件为
当k=n时取等
拓展:当胜利+2,平局各+1,失败+0时,把上面定理中\(\binom{k}{2}\)乘2即可
三元环计数
考虑算非三元环
找三元环
我们知道一个竞赛图如果存在一个环,那么它一定存在一个三元环。
所以直接dfs就行了。
三元环期望
就是 \(n\) 个点的竞赛图给定了 \(m\) 条边的方向,剩下的方向都不确定,求期望三元环个数。
这里我们先计算出确定的出度g以及入度d。然后记\(u_i\)表示\(n-1-d_i-g_i\)即某个点连出去的未确定方向的边数。
那么根计数的公式,得到: