Stoer-Wagner 算法

本文详细介绍了Stoer-Wagner算法,一种用于求解无向图全局最小割的有效方法。通过逐步缩点和求最小割的过程,该算法能够在多项式时间内找到任意两点间最小割的最小值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

求一个任意的无向图的全局最小割。即,定义λ(x,y)\lambda(x,y)λ(x,y)表示x,yx,yx,y两点之间的最小割,给出一张任意的无向图,你需要求出min⁡x≠yλ(x,y)\min_{x\neq y}\lambda(x,y)minx=yλ(x,y)

Stoer-Wagner 算法

约定

w(x,y)w(x,y)w(x,y)表示x,yx,yx,y之间的边权。用c(X,Y)c(X,Y)c(X,Y)表示∑x∈X,y∈Yw(x,y)\sum_{x\in X,y\in Y} w(x,y)xX,yYw(x,y),其中X,YX,YX,Y是图中点集的两个子集。

定义contract(x,y)表示将x,yx,yx,y两个点缩起来,具体来说就是新建一个点uuu,对于任意v≠x,v≠yv\neq x,v\neq yv=x,v=y,令w(u,v)=w(v,x)+w(v,y)w(u,v) = w(v,x) + w(v,y)w(u,v)=w(v,x)+w(v,y),然后将x,yx,yx,y从原图中删去。

算法过程

如果两个点在全局最小割的异侧,那么它们之间的最小割就是全局最小割;否则,将它们缩起来对全局最小割没有影响。

Stoer-Wagner算法的过程是:每一次求出两个点的最小割,然后把它们缩起来。整个算法过程中求出过的最小割的最小值就是全局最小割。

但是这样还是要求n−1n-1n1次最小割。

优化:MinimumCutPhase

我们并不是需要求某两个点之间的最小割,只要我们求出的是某两个点之间的最小割就可以了。

MinimumCutPhase可以在O(n2)O(n^2)O(n2)的时间内求出某两个点之间的最小割,以下是它的过程:

  1. 首先随便选择一个点aaa,令A={a}A=\{a\}A={a}
  2. 然后选择一个点不在AAA中的点xxx,使得c(A,{x})c(A,\{x\})c(A,{x})最大,然后将xxx加入AAA
  3. 重复2.直到AAA以外只剩下一个点。则我们最后加入AAA的那个点和剩下的那个点(设为zzz)之间的最小割就是c(A,{z})c(A,\{z\})c(A,{z})

正确性:实际上可以证明,假设加入AAA的点依次为v1=a,v2⋯vn−1v_1=a,v_2\cdots v_{n-1}v1=a,v2vn1,令最后剩下的那个点为vnv_nvn,那么对于任意的i≥2i\ge 2i2,在只考虑v1,v2⋯viv_1,v_2\cdots v_iv1,v2vi以及它们之间的边的时候,viv_ivivi−1v_{i-1}vi1之间的最小割是c({v1,v2,⋯vi−1},{vi})c(\{v_1,v_2,\cdots v_{i-1}\},\{v_i\})c({v1,v2,vi1},{vi})

由于vi,vi−1v_i,v_{i-1}vi,vi1的任意一个割都会删掉(vi,vi−1)(v_i,v_{i-1})(vi,vi1)这条边,所以λ(vi,vi−1)\lambda(v_i,v_{i-1})λ(vi,vi1)等于将(vi,vi−1)(v_i,v_{i-1})(vi,vi1)删掉之后求得的最小割λ′(vi,vi−1)\lambda'(v_i,v_{i-1})λ(vi,vi1)加上w(vi,vi−1)w(v_i,v_{i-1})w(vi,vi1)。所以接下来只考虑将(vi,vi−1)(v_i,v_{i-1})(vi,vi1)删掉后的图。

首先证明在只考虑v1,v2,⋯viv_1,v_2,\cdots v_iv1,v2,vi以及它们之间的边的时候,c({v1,v2,⋯vi−1},{vi})≤λ(vi−1,vi−2)c(\{v_1,v_2,\cdots v_{i-1}\},\{v_i\})\le \lambda(v_{i-1},v_{i-2})c({v1,v2,vi1},{vi})λ(vi1,vi2)。用归纳法。对于i=2i=2i=2显然成立。对于i>2i>2i>2

  • viv_ivi以及与viv_ivi相邻的所有边从图中删掉,此时vi−1v_{i-1}vi1vi−2v_{i-2}vi2的最小割是({v1,v2,⋯vi−2},{vi−1})(\{v_1,v_2,\cdots v_{i-2}\},\{v_{i-1}\})({v1,v2,vi2},{vi1})(归纳假设)。
  • 由MinimumCutPhase的过程可以知道
    c({v1,v2⋯vi−2},{vi})≤c({v1,v2,⋯vi−2},{vi−1})(1) c(\{v_1,v_2\cdots v_{i-2}\},\{v_i\}) \le c(\{v_1,v_2,\cdots v_{i-2} \},\{v_{i-1}\}) \tag{1} c({v1,v2vi2},{vi})c({v1,v2,vi2},{vi1})(1)
  • 由于viv_ivivi−1v_{i-1}vi1之间没有边,所以
    c({v1,v2,⋯vi−2},{vi−1})=c({v1,v2,⋯vi−2,vi},{vi−1})c({v1,v2⋯vi−2},{vi})=c({v1,v2⋯vi−2,vi−1},{vi}) c(\{v_1,v_2,\cdots v_{i-2}\},\{v_{i-1}\}) = c( \{v_1,v_2,\cdots v_{i-2},v_i\},\{v_{i-1}\})\\ c(\{v_1,v_2\cdots v_{i-2}\},\{v_i\})= c(\{v_1,v_2\cdots v_{i-2},v_{i-1}\},\{v_i\}) c({v1,v2,vi2},{vi1})=c({v1,v2,vi2,vi},{vi1})c({v1,v2vi2},{vi})=c({v1,v2vi2,vi1},{vi})
  • 将上面的两个式子带入(1),可以得到
    c({v1,v2⋯vi−2,vi−1},{vi})≤c({v1,v2,⋯vi−2,vi},{vi−1}) c(\{v_1,v_2\cdots v_{i-2},v_{i-1}\},\{v_i\}) \le c(\{v_1,v_2,\cdots v_{i-2},v_i \},\{v_{i-1}\}) c({v1,v2vi2,vi1},{vi})c({v1,v2,vi2,vi},{vi1})
  • 由于c({v1,v2,⋯vi−2,vi},{vi−1})c(\{v_1,v_2,\cdots v_{i-2},v_i \},\{v_{i-1}\})c({v1,v2,vi2,vi},{vi1})等于加入viv_ivi这个点之前图中的vi−1,vi−2v_{i-1},v_{i-2}vi1,vi2的最小割,并且在加入viv_ivi之后两个点的最小割不可能变得比加入之前更小,所以c({v1,v2,⋯vi−2,vi},{vi−1})=λ(vi−1,vi−2)c(\{v_1,v_2,\cdots v_{i-2},v_i \},\{v_{i-1}\})=\lambda(v_{i-1},v_{i-2})c({v1,v2,vi2,vi},{vi1})=λ(vi1,vi2)。所以我们得到了
    c({v1,v2⋯vi−2,vi−1},{vi})≤λ(vi−1,vi−2) c(\{v_1,v_2\cdots v_{i-2},v_{i-1}\},\{v_i\}) \le \lambda(v_{i-1},v_{i-2}) c({v1,v2vi2,vi1},{vi})λ(vi1,vi2)

然后我们将证明,只考虑v1,v2,⋯viv_1,v_2,\cdots v_iv1,v2,vi以及它们之间的边的时候,c({v1,v2,⋯vi−1},{vi})≤λ(vi,vi−2)c(\{v_1,v_2,\cdots v_{i-1}\},\{v_i\})\le \lambda(v_{i},v_{i-2})c({v1,v2,vi1},{vi})λ(vi,vi2)。用归纳法。对于i=2i=2i=2显然成立。对于i>2i>2i>2

  • 删去vi−1v_{i-1}vi1以及原图中与它相邻的边。对得到的图重新进行MinimumCutPhase,最后加入AAA的点是vi−2v_{i-2}vi2,剩下的点是viv_ivi
  • 此时vi,vi−2v_i,v_{i-2}vi,vi2之间的最小割是c({v1,v2,⋯vi−2},{vi})c(\{v_1,v_2,\cdots v_{i-2}\},\{v_i\})c({v1,v2,vi2},{vi})
  • vi−1v_{i-1}vi1加回去之后的图中,得到λ(vi,vi−2)=c({v1,v2,⋯vi−2,vi−1,vi})\lambda(v_i,v_{i-2}) = c(\{v_1,v_2,\cdots v_{i-2},v_{i-1},v_i\})λ(vi,vi2)=c({v1,v2,vi2,vi1,vi})

综合以上两个结论:

c({v1,v2,⋯vi−2,vi−1},{vi})=λ(vi,vi−2)c({v1,v2⋯vi−2,vi−1},{vi})≤λ(vi−1,vi−2)⟹c({v1,v2,⋯vi−1},{vi})≤min⁡{λ(vi,vi−1),λ(vi−1,vi−2} c(\{v_1,v_2,\cdots v_{i-2},v_{i-1}\},\{v_i\})=\lambda(v_i,v_{i-2})\\ c(\{v_1,v_2\cdots v_{i-2},v_{i-1}\},\{v_i\}) \le \lambda(v_{i-1},v_{i-2}) \\ \Longrightarrow c(\{v_1,v_2,\cdots v_{i-1}\},\{v_i\})\le \min\{\lambda(v_i,v_{i-1}),\lambda(v_{i-1},v_{i-2}\} c({v1,v2,vi2,vi1},{vi})=λ(vi,vi2)c({v1,v2vi2,vi1},{vi})λ(vi1,vi2)c({v1,v2,vi1},{vi})min{λ(vi,vi1),λ(vi1,vi2}

以及

λ(x,y)≥min⁡{λ(y,z),λ(x,z)} \lambda(x,y) \ge \min \{ \lambda(y,z),\lambda(x,z)\} λ(x,y)min{λ(y,z),λ(x,z)}

以及
c({v1,v2,⋯vi−1},{vi})≥λ(vi,vi−1) c(\{v_1,v_2,\cdots v_{i-1}\},\{v_i\}) \ge \lambda(v_i,v_{i-1}) c({v1,v2,vi1},{vi})λ(vi,vi1)

可以得到
c({v1,v2,⋯vi−1},{vi})=λ(vi,vi−1) c(\{v_1,v_2,\cdots v_{i-1}\},\{v_i\}) = \lambda(v_i,v_{i-1}) c({v1,v2,vi1},{vi})=λ(vi,vi1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值