图论
图论
本文旨在整理一些比较冷门的图论算法。
斯坦纳树
在一个 \(n\) 个点的图上花费最小的代价连通 \(k\) 个关键点。
设 \(f(i,S)\) 表示以 \(i\) 为根的连通了集合 \(S\) 的最小代价。
转移考虑一个点是只有一个儿子还是有多个儿子:
- \(f(i,S)\leftarrow f(j,S)+w(i,j)\)
- \(f(i,S)\leftarrow f(i,T)+f(i,S-T),T\subset S\)
按 \(S\) 升序转移,先枚举子集转移后者,再跑最短路算法转移前者。
时间复杂度 \(O(n\times 3^k+2^km\log n)\)。
斯坦纳树的做法也启发我们对于一些树的结构可以大力状压 DP 子树点集合。
同余最短路
对于一类给定一个数集,可以任意取多次想刻画能凑出的数,可以使用同余最短路。
传统的做法是考虑将数集里的最小值拿出来对模其意义下的每个同余类考虑最小凑出来的数是什么。对于其它数集里的数建边跑最短路就行了。
同余最短路问题也可以使用更好写的转圈做法得到很好的解决:wls 的博客。
图的最小环
无向图。
我们考虑统计图中过一个顶点 \(x\) 的最小环。
建立这个点的最短路树,将最短路上 \(x\) 的儿子作为标记赋予儿子子树内的所有点,\(x\) 的标记是自己。那么我们可以考虑枚举一条两端标记不同的边 \((u,v)\)(不考虑 \(x\) 到儿子的边),考察 \(x\to u,u\to v,v\to x\) 这个环。过 \(x\) 的最小环显然可以通过这样的枚举方法被枚举到。
对于单点复杂度 \(O(n^2+m)\) 或者 \(O(m\log n+m)\)。
直接统计整个图的最小环有更简单的做法,直接考虑 Floyed。
Floyed 的最外层枚举是说考虑了 \([1,k]\) 作为中转点,此时求出的最短路数组,一定没有过非起点终点的 \((k,n]\),我们考虑一个最小环在环上编号最大的点处被统计答案。
枚举和 \(k\) 相邻的两个环上的点 \(i,j\) 将 \(w(i,k)+w(k,j)+f(i,j)\) 贡献到答案即可。
时间复杂度 \(O(n^3)\)。
二分图最大权匹配
学不会 KM,推荐大家学习原始对偶,复杂度 \(O(n^3)\),但是常数比较大。
原始对偶算法的思想和 Johnson 最短路的思想类似,通过势能将带负权图转化成非负边权图,使用 dijkstra 跑费用流。
初始的势能取为源点到每个点的最小距离,使用一次 spfa 完成这项工作。
\((u,v)\) 的新边权为 \(h_u-h_v+w\)。
与 Johnson 不同的地方在于,我们增广了最短路后,图的形态会发生变化,我们需要修改我们的势能函数。
结论是每次增广后给势能函数 \(h_u\) 加上我们刚刚在新图上跑出的源点到每个点的最短路即可。
时间复杂度是 \(O(nm+n^3)\),二分图边很少可以使用堆优化 dij 做到 \(O(nm+nm\log n)\)。
一般图最大匹配
写不出带花树,线代做法也好困难。
真碰到还是写随机化吧,虽然随机化已经能被卡了但 OI 赛制出题人不会卡掉太多分的?
随机化的思路是随机调整,不同于一般的找环,找链的增广路,调整法只找长度为奇数的简单路。
哦原来一般图最大匹配是 10 级,那都可以毁灭了。
最小化 DFA
OI 中的应用大概是一些自动机题。
等价类划分算法
对于爆搜出来的一个状态数较大的 DFA,我们希望对其最小化以提升 DP 速度。
我们从一个终止状态和一个初始状态两个节点的 DFA 开始,将除终止节点外的节点放在初始节点上。
我们跑若干轮如下的算法,直到无法分裂出更多节点停止:
对于每个节点,将其代表的所有原 DFA 节点按本质不同出边集合分裂成若干等价类,并进行一些重新标号。
时间复杂度 \(O(|E||S|)\),\(|E|\) 为原 DFA 边数,\(|S|\) 为最小化 DFA 后点数(用于估计算法运行轮数)。实测轮数一般远小于这个粗略的估计。
hopcroft 鸽了。