前言

StoerWagner算法是一个找出无向图全局最小割的算法,本文需要读者有一定的图论基础。

本文大部分内容与词汇来自参考文献(英文,需科学上网),用兴趣的可以去读一下文献。


概念

  • 无向图的割:有无向图\(G=(V,E)\),设\(C\)为图\(G\)中一些弧的集合,若从\(G\)中删去\(C\)中的所有弧能使图\(G\)不是连通图,称\(C\)图\(G\)的一个割。
  • \(S-T\)割:使得顶点\(S\)与顶点\(T\)不再连通的割,称为\(S-T\)割
  • \(S-T\)最小割:包含的弧的权和最小的\(S-T\)割,称为\(S-T\)最小割。
  • 全局最小割:包含的弧的权和最小的割,称为全局最小割。
  • 诱导割(induced cut):令图\(G=(V, E)\)的一个割为\(C\),则割\(C\)在图\(G\)的子图\(G'=(V',E')\)中的部分称为割\(C\)的诱导割。(类似于概念诱导子图(induced subgraph)

算法流程

大致流程

step1:在图\(G\)中找出任意\(s-t\)最小割cut-of-the-phase

step2:合并\(s\)、\(t\),重复执行step1直到图G只剩下一个顶点

step3:输出最小的cut-of-the-phase为最终结果

伪代码:

def MinimumCutPhase(G, w, a):
A ← {a}
while A ≠ V:
把与A联系最紧密(most tightly)的顶点加入A中
cut-of-the-phase ← w(A \ t, t)
合并最后两个加入到A的顶点s、t
return cut-of-the-phase def StoerWagner(G, w, a):
while |V| > 1
MinimumCutPhase(G, w, a)
根据返回值更新最小割

其中:

  • \(w\)为边权函数,\(w(e)\)为边\(e\)的权值大小
  • \(w(A, v)\)为顶点\(v\)到集合\(A\)的所有边权和
  • \(x\)与\(A\)联系最紧密(most tightly)当且仅当\(x \notin A\)且\(w(A,x) = max\{w(A, y) | y \notin A\}\)
  • \(a\)可以取任意顶点作为算法的初始顶点

证明

首先,算法基于这样一个事实:

两个顶点s、t,要么在全局最小割的同一个集合中,要么在不同的集合中

那么结果便只可能在是\(s-t\)最小割,或者合并\(s\)、\(t\)的新图的全局最小割。

然后问题就在于如何寻找任意的\(s-t\)最小割。现在来证明MinimumCutPhase找出来的\(s-t\)割cut-of-the-phase为什么是最小的。

定理:每个阶段割(cut-of-the-phase)是当前图的\(s-t\)最小割,\(s\)、\(t\)是当前阶段最后加入的结点。

证明:

以加入集合\(A\)的顺序组成一个序列,以\(a\)为开始,以\(s\)、\(t\)结束。然后来证明对于任意\(s-t\)割\(C\)均不小于阶段割(cut-of-the-phase)

我们称结点\(v\)(\(v \neq a\))是活跃的(active)当\(v\)和\(v\)的前一个结点分立于C的两边。令\(w(C)\)为割C的大小,\(A_v\)为所有在\(v\)前面的顶点(不包括\(v\)),\(C_v\)为\(A_v \bigcup \{v\}\)的\(C\)割,\(w(C_v)\)为诱导割\(C_v\)的大小。

那么,对于所有活跃的顶点v,有

\[w(A_v,v) \leq w(C_v) \cdots \cdots (1)
\]

归纳证明:

对于第一个活跃顶点\(v_0\),该不等式以等号成立。这是由于\(v_0\)前面的点都非活跃点,那么它们都在割C的同一侧,另一侧为\(v_0\),显然有\(w(A_{v_0},v_0) = w(C_{v_0})\)。

假设对于活跃顶点\(v\),\(v\)满足不等式。令\(u\)为\(v\)的下一个活跃顶点,那么我们令:

\[w(A_u,u)=w(A_v,u)+w(A_u \setminus A_v,u)=:\alpha
\]

由于\(v\)加入\(A\)比\(u\)早,所以有\(w(A_v,u) \leq w(A_v,v)\)。又因\(v\)满足不等式,所以有

\[w(A_v,u) \leq w(A_v,v) \leq w(C_v)
\]

由于所有 \(A_u \setminus A_v\) 与\(u\)之间的边均跨过割\(C_u\),且不是\(C_v\)的一部分,于是有

\[w(C_v)+w(A_u \setminus A_v,u) \leq w(C_u)
\]

联立上式,得到:

\[\alpha \leq w(C_v)+w(A_u \setminus A_v,u) \leq w(C_u)
\]

于是对于任意活跃顶点,均满足不等式\((1)\)。

由于\(t\)总是活跃顶点(\(s-t\)割导致\(s\)与\(t\)总被割开),则\(t\)总是满足不等式\(w(A_t,t) \leq
w(C_t)\),即任意割小于等于\(w(A_t,t)\)。又因为\(w(A_t,t)\)为单独割掉顶点\(t\)的大小(链接\(t\)的所有边权和),所以有\(w(A_t,t)\)为\(s-t\)最小割。证得MinimumCutPhase找出来的\(s-t\)割是\(s-t\)最小割。


例题

HDU 3691 Nubulsa Expo(全局最小割Stoer-Wagner算法)

HDU 6081 度度熊的王国战略(全局最小割Stoer-Wagner算法)


参考文献

stoerwagner-mincut.[Stoer-Wagner,Prim,连通性,无向图,最小边割集]

全局最小割StoerWagner算法详解的更多相关文章

  1. HDU 3691 Nubulsa Expo(全局最小割Stoer-Wagner算法)

    Problem Description You may not hear about Nubulsa, an island country on the Pacific Ocean. Nubulsa ...

  2. HDU 6081 度度熊的王国战略(全局最小割Stoer-Wagner算法)

    Problem Description 度度熊国王率领着喵哈哈族的勇士,准备进攻哗啦啦族. 哗啦啦族是一个强悍的民族,里面有充满智慧的谋士,拥有无穷力量的战士. 所以这一场战争,将会十分艰难. 为了更 ...

  3. 全局最小割Stoer-Wagner算法

    借鉴:http://blog.kongfy.com/2015/02/kargermincut/ 提到无向图的最小割问题,首先想到的就是Ford-Fulkerson算法解s-t最小割,通过Edmonds ...

  4. SW算法求全局最小割(Stoer-Wagner算法)

    我找到的唯一能看懂的题解:[ZZ]最小割集Stoer-Wagner算法 似乎是一个冷门算法,连oi-wiki上都没有,不过洛谷上竟然有它的模板题,并且2017百度之星的资格赛还考到了.于是来学习一下. ...

  5. POJ 2914:Minimum Cut(全局最小割Stoer-Wagner算法)

    http://poj.org/problem?id=2914 题意:给出n个点m条边,可能有重边,问全局的最小割是多少. 思路:一开始以为用最大流算法跑一下,然后就超时了.后来学习了一下这个算法,是个 ...

  6. poj 2914&&hdu 3002 全局最小割Stoer-Wagner算法模板

    #include<stdio.h> #include<string.h> #include<iostream> #define inf 0x3fffffff #de ...

  7. [全局最小割][Stoer-Wagner 算法] 无向图最小割

    带有图片例子的 [BLOG] 复杂度是$(n ^ 3)$ HDU3691 // #pragma GCC optimize(2) // #pragma GCC optimize(3) // #pragm ...

  8. 最小割Stoer-Wagner算法

    最小割Stoer-Wagner算法 割:在一个图G(V,E)中V是点集,E是边集.在E中去掉一个边集C使得G(V,E-C)不连通,C就是图G(V,E)的一个割: 最小割:在G(V,E)的所有割中,边权 ...

  9. 无向图最小割Stoer-Wagner算法学习

    无向连通网络,去掉一个边集可以使其变成两个连通分量则这个边集就是割集,最小割集当然就权和最小的割集. 使用最小切割最大流定理: 1.min=MAXINT,确定一个源点 2.枚举汇点 3.计算最大流,并 ...

随机推荐

  1. IIS 部署SSL证书

    1.导入证书 打开IIS服务管理器,点击计算机名称,双击‘服务器证书 双击打开服务器证书后,点击右则的导入 选择证书文件,点击确定 2.站点开启SSL 选择证书文件,点击确定 点击网站下的站点名称,点 ...

  2. Hash Tables

    哈希表 红黑树实现的符号表可以保证对数级别的性能,但我们可以做得更好.哈希表实现的符号表提供了新的数据访问方式,插入和搜索操作可以在常数时间内完成(不支持和顺序有关的操作).所以,在很多情况下的简单符 ...

  3. 【Alpha 冲刺】 9/12

    今日任务总结 人员 今日原定任务 完成情况 遇到问题 贡献值 胡武成 完善API文档,并初步使用SpringMVC产生编写部分API 已完成 孙浩楷 完成课程通知页面(及发布通知的弹窗) 已完成 胡冰 ...

  4. python第三十二课——栈

    栈:满足特点 --> 先进后出,类似于我们生活中的子弹夹 [注意] 对于栈结构而言:python中没有为其封装特定的函数,我们可以使用list(列表)来模拟栈的特点 使用list对象来模拟栈结构 ...

  5. 微信jsapi退款操作

    引自网络“ 前期准备:当然是搞定了微信支付,不然怎么退款,这次还是使用官方的demo.当然网上可能也有很多大神自己重写和封装了demo,或许更加好用简洁,但是我还是不提倡用,原因如下:(1)可能功能不 ...

  6. python json格式字符串转换为字典格式

    不废话,看代码 #_*_ coding:utf- _*_ import os import json course=open('C:\\Users\\ly199\\Desktop\\list.txt' ...

  7. Python2.7-marshal

    marshal模块,和 pickle 模块功能基本相同,也是序列化数据,只不过 marshal 都序列化成二进制数据,由于没有官方统一,不同版本 marshal 的结果也会不一样,所以不推荐使用.ma ...

  8. Android failed to start daemon

    异常描述:在Eclipse中运行Android项目时Console中出现: The connection to adb is down, and a severe error has occured. ...

  9. linux 创建守护进程的相关知识

    linux 创建守护进程的相关知识 http://www.114390.com/article/46410.htm linux 创建守护进程的相关知识,这篇文章主要介绍了linux 创建守护进程的相关 ...

  10. odoo创建编号

    def create(self,cr,uid,vals,context=None): if context is None: context ={} print 111111 print vals[] ...