无向图最小割
有关规定:
- 一.Gomory-Hu树
定义一棵树 \(T=(V,E_T)\) 为最小割树,当且仅当 \(δ(W)\) 是某个 \(α(s,t)\),\(W\) 是 \(T\) 删去边 \((s,t)\) 后其中一个联通块
实现:
这个做法的主要问题在于为什么边 \((r',r'')\) 是合法的
首先我们知道 \(\alpha(r_1,r_2)\) 是 \(r',r''\) 的一组割,那么我们需要证明的就是 \(λ(r',r'')\ge λ(r_1,r_2)\)
考虑一般情况即 \(r_1\ne r',r_2\ne r''\)
如果 \(λ(r_1,r')<λ(r_1,r_2)\),由于 \(v_1\in C_{r'}^1\),即这次之后 \(r'\) 和 \(v_1\) 始终未被割开
又因为 \(r_1\) 与 \(r'\) 最终一定已经被割开,可知 \(λ(r_1,r')\) 也是 \(r_1,r_2\) 的一个割
那么 \(λ(r_1,r')< λ(r_1,r_2)\) 就与 \(λ(r_1,r_2)\) 是最小割矛盾了
所以 \(λ(r_1,r')\ge λ(r_1,r_2)\)
那么 \(λ(r',r'')\ge max(λ(r',r_1),λ(r_1,r_2),λ(r_2,r''))=λ(r_1,r_2)\)
非递归实现:
考虑递归的过程我们其实不是那么在意递归的顺序,只是在不停地拆分点集直到所有点集大小都为 \(1\)
考虑这样的做法:
每个时刻,用每个点集中最小的点来代表这个点集,对每个点记录 \(fa_u\)
如果 \(u\) 就是集合的代表点,那么 \((fa_u,u)\) 代表一条真正的Gomory-Hu树边,否则代表归属关系
每次枚举所有点,对于每一条是归属关系的边进行拆分
设 \(v=fa_u\),先求出 \((u,v)\) 的最小割
那么考虑划分情况,首先对于所有被划分到 \(u\) 一侧且 \(fa=v\) 的点的 \(fa\) 设为 \(u\) 且边权不变
然后还需要特殊考虑 \(fa_v\) 被划分到了 \(u\) 一侧的情况,需要把 \(fa_u\) 设为 \(fa_v\)
最后考虑在两个点集之间连上一条边权为最小割的边,如果 \(fa_v\) 不在 \(u\) 一侧就令 \(fa_u=v\) 来代表这条边
否则令 \(fa_v=u\) 来代表这条边
- 二.等价流树
定义一棵树 \(T=(V,E_T)\) 等价流树,\((s,t)\) 路径上的最小权值就是两个点的最小割
等价流树的构造更加简单,每次求出 \((s,t)\) 的最小割后直接连边 \((s,t,maxflow)\) 就行了
- 三.全局最小割
无向图中最小的一个割
显然的,我们可以直接通过求最小割树/等价流树来解决这个问题
但我们有复杂度更好的做法
Stoer-Wagner算法
我们知道任意两个点要么在全局最小割的一侧,要么他们的最小割就是全局最小割
所以我们只要每次随便找两个点然后合并最后就能得到全局最小割
随意找两个点之间的最小割可以用最大邻接搜索算法
Karger算法
不带权图:每次随机选取两个点缩点并删掉自环,直到只剩下两个点
经过证明发现运行一次算法的正确率是 \(\binom{|V|}{2}^{-1}\),那么只要运行 \(|V|^2\) 次就可以得到一个常数正确率了
带权图:带边权的一条边可以看作边权条重边,但我们需要修改每条边被选中的概率才能保证正确率
显然的,一条边被选中的概率应该是该边边权占所有边权的比例
具体实现中,我们维护一个边的有序集合
每次在[0,剩下的边权和]中随机选一个数x,找到集合中第一条边使得他之前所有边边权之和不小于这个数,这个集合可以树状数组维护