前言

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. 使用TuShare下载历史逐笔成交数据并生成1分钟线

    使用如下代码从TuShare下载沪深300每只股票的历史成交记录并按股票.日期保存到本地.主要是为了以后查询方便快速. #-*- coding: utf-8 -*- import numpy as n ...

  2. 启动android monitor报错解决办法

    再这汇总一下这段时间使用android monitor新遇到的问题,特汇总对应问题解决办法如下: 1.确保JDK和Android studio位数相同,比如JDK使用的是64位,studio也要是64 ...

  3. Scala学习之路 (四)Scala的数组、映射、元组、集合

    一.数组 1.定长数组和变长数组 import scala.collection.mutable.ArrayBuffer object TestScala { def main(args: Array ...

  4. Odoo作为App后端时如何调试App

    转载请注明原文地址:https://www.cnblogs.com/cnodoo/p/9307340.html  一:Odoo可以作为app后台+后台管理系统使用 Odoo作为一个可供二次开发的框架, ...

  5. scapy学习笔记(1)

    转载请注明:小五义 http://www.cnblogs.com/xiaowuyi scapy是python写的一个功能强大的交互式数据包处理程序,可用来发送.嗅探.解析和伪造网络数据包,常常被用到网 ...

  6. php操作url 函数等

    pathinfo() - Returns information about a file path parse_str() - Parses the string into variables pa ...

  7. Advanced Electronic Engineer

    Job Title Advanced Electronic Engineer Job Description In this role, you have the opportunity to Be ...

  8. word导入导出自定义属性列表

    Sub ExportCustom() ' ' ExportCustom 宏 ' 导出自定义属性到custom.txt ' Dim lFileNumber As Long Dim sFilePath A ...

  9. Alamofire请求网络

    HTTP - GET和POST请求- 如果要传递大量数据,比如文件上传,只能用POST请求- GET的安全性比POST要差些,如果包含机密/敏感信息,建议用POST- 如果仅仅是索取数据(数据查询), ...

  10. Scala--映射和元组

    一.构造映射 val scores = Map("Jim"->10, ("Tom",20), "Sam"->44) //key- ...