题意:求全局最小割

不能用网络流求最小割,枚举举汇点要O(n),最短增广路最大流算法求最大流是O(n2m)复杂度,在复杂网络中O(m)=O(n2),算法总复杂度就是O(n5);就算你用其他求最大流的算法,算法总复杂度也要O(n4)。所以用网络流算法求解最小割集复杂度不会低于O(n4)。所以就要用Stoer_Wagner算法。算法复杂度为O(n3)。如果加堆优化,复杂度会降为O(n2logn)。

Stoer_Wagner算法: 
Stoer_Wagner算法是求无向图全局最小割的一个有效算法,最坏时间复杂度O(n3),主要思想是先找任意2点的最小割,然后记录下这个最小割,再合并这2个点。这样经过n−1次寻找任意2点最小割,每次更新全局最小割。最后整张图缩成一个点,算法结束,所保存下来的最小割就是全局最小割。

具体步骤

如果G的最小割Cut把G分成M,N两个点集,那么枚举的s和t无非以下两种情况:

①:如果s∈M,t∈N则Min-C(s,t) = Cut(最终的最小割)

②:如果s,t∈M(或s,t∈N)则Min-C (s,t) >= Cut(合并s和t后并不影响最小割,所以就把st合并了得到中间结果图G',继续在图G'上求最小割直到命中条件①)

因为利用到了中间结果G',G'<G,所以降低了复杂度。另外,这个合并的思想有点像Prim最小生成树算法,prim维护的dis数组的含义是集合A外的点到到集合树的最短边权,而Stoer−Wagner维护的w数组是集合A外的点,到集合A所有点的边权之和【割集】。

至于②中提到的合并操作,定义为Contract(s,t) := 删掉点 s, t 及边(s, t),加入新节点 c,对于任意 v ∈ 与s,t联通的点集,做一条新的边w(v, c) = w(c, v) = w(s, v) + w(t, v)

. 设最小割cut=INF, 任选一个点s到集合A中, 定义W(A, p)为A中的所有点到A外一点p的权值总和.

. 对刚才选定的s, 更新W(A,p)(该值递增).

. 选出A外一点p, 且W(A,p)最大的作为新的s, 若A!=|V|, 则继续2. //最大割

4. 把最后进入A的两点记为s和t, 用W(A,t)更新cut.

5. 合并st,即新建顶点u, 边权w(u, v)=w(s, v)+w(t, v), 删除顶点s和t, 以及与它们相连的边

. 若|V|!=1则继续1.

Stoer−Wagner的正确性: 
设S和T是图G的2个顶点,图G的全局最小割要么是S−T的最小割,此时S和T在G的全局最小割的2个不同的子集中,要么就是G中将S和T合并得的的新图G′的全局最小割,此时S和T在G的全局最小割的同一子集中。

合并后对边权进行调整对全局最小割没有任何影响。所以只需要不断求出当前图中任意2个点的最小割,然后合并这2个点。不断缩小图的规模求得最小割。

       5,6合并成        

 #include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; int e[][]; //边权
int w[]; //各点与A集合中所有点的边权之和, w(A,x)=∑w(id[i],x) id[i]∈A
int id[]; //顶点的重新索引,由于合并顶点的需要
bool vis[]; //顶点是否已访问 int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(e,, sizeof(e));
for(int i=;i<n;i++)id[i]=i;//未合并之前,各顶点索引自己
for(int i=;i<m;i++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
e[u][v]+=c;
e[v][u]+=c;//无向图
} int ans=0x3f3f3f3f;//全局最小割
while(n>)
{
memset(vis,, sizeof(vis));
memset(w,, sizeof(w));
int s,t=;//最后两个顶点
vis[]=;//默认第一个顶点入集合A
for(int i=;i<n;i++)
{
s=t;
t=-;
for(int j=;j<n;j++)
{
if(!vis[j])
{
w[j]+=e[id[j]][id[s]];
if(t==-||w[j]>w[t])t=j;//找最大的割集
}
}
vis[t]=; //加入集合A
}
ans=min(ans,w[t]);
for(int i=;i<n;i++) // 合并s,t为s点
{
if(i==s||i==t)continue;
e[id[i]][id[s]]+=e[id[i]][id[t]];
e[id[s]][id[i]]+=e[id[i]][id[t]]; //边权w(s, v)=w(s, v)+w(t, v)
}
id[t]=id[--n]; // 赋值顶点n-1从而删除t点, 顶点数量-1
}
printf("%d\n",ans);
}
return ;
}

参考自:http://www.hankcs.com,yogykwan和QAQqwe

POJ 2914 Minimum Cut【最小割 Stoer-Wangner】的更多相关文章

  1. POJ 2914 Minimum Cut 最小割图论

    Description Given an undirected graph, in which two vertices can be connected by multiple edges, wha ...

  2. POJ 2914 Minimum Cut 最小割算法题解

    最标准的最小割算法应用题目. 核心思想就是缩边:先缩小最大的边.然后缩小次大的边.依此缩小 基础算法:Prime最小生成树算法 只是本题測试的数据好像怪怪的,相同的算法时间执行会区别非常大,并且一样的 ...

  3. POJ2914 Minimum Cut —— 最小割

    题目链接:http://poj.org/problem?id=2914 Minimum Cut Time Limit: 10000MS   Memory Limit: 65536K Total Sub ...

  4. POJ 2914 Minimum Cut Stoer Wagner 算法 无向图最小割

    POJ 2914 题意:给定一个无向图 小于500节点,和边的权值,求最小的代价将图拆为两个联通分量. Stoer Wagner算法: (1)用类似prim算法的方法求"最大生成树" ...

  5. POJ 2914 Minimum Cut (全局最小割)

    [题目链接] http://poj.org/problem?id=2914 [题目大意] 求出一个最小边割集,使得图不连通 [题解] 利用stoerwagner算法直接求出全局最小割,即答案. [代码 ...

  6. POJ 2914 Minimum Cut 全局最小割

    裸的全局最小割了吧 有重边,用邻接矩阵的时候要小心 #include<iostream> #include<cstdio> #include<bitset> #in ...

  7. POJ 2914 - Minimum Cut - [stoer-wagner算法讲解/模板]

    首先是当年stoer和wagner两位大佬发表的关于这个算法的论文:A Simple Min-Cut Algorithm 直接上算法部分: 分割线 begin 在这整篇论文中,我们假设一个普通无向图G ...

  8. POJ 2914 Minimum Cut

    Minimum Cut Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 9319   Accepted: 3910 Case ...

  9. HDU 6214 Smallest Minimum Cut 最小割,权值编码

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6214 题意:求边数最小的割. 解法: 建边的时候每条边权 w = w * (E + 1) + 1; 这 ...

随机推荐

  1. sublime修改侧边栏字体

    安装了sublime的material主题后,侧边栏的字体特别小,设置方法如下: 安装插件 用上面的插件打开 Material-Theme.sublime-theme 如下 { "class ...

  2. Flash硬件原理

    1.2.1. 什么是Flash Flash全名叫做Flash Memory,从名字就能看出,是种数据存储设备,存储设备有很多类,Flash属于非易失性存储设备(Non-volatile Memory ...

  3. linux学习之硬盘的存储原理和内部架构

    原文地址:https://blog.csdn.net/tanggao1314/article/details/52074735 首先,让我们看一下硬盘的发展史: 1956年9月13日,IBM的IBM ...

  4. $Django patch与put,视图组件,路由控制,响应器

    1 patch与put(幂等?回顾) PATCH 与 PUT 属性上的一个重要区别还在于:PUT 是幂等的,而 PATCH 不是幂等的.幂等是一个数学和计算机学概念,在计算机范畴内表示一个操作执行任意 ...

  5. Mysql 数据库增删改查

    数据插入 语法:INSERT INTO Table_name(field1,field2……fieldN) values(value1,vlaue2,…valueN) 单行插入用户类型 INSERT ...

  6. 用sitemap做主页的菜单栏

    首先打开vs--> 新建项-->选择站点地图. 站点地图建好了  其中具体的节点根据自己情况配好就行. 接下来是两个非常重要的类: using System.Collections.Gen ...

  7. python 安装mysql报错

    原 安装Python mysqlclient出现“OSError: mysql_config not found”错误 2016年06月01日 12:15:11 wangtaoking1 阅读数:11 ...

  8. 如何取出DataTable中某几个字段(列名)组合新表

    在偶不知道第二种方法之前.偶费了好大劲才把这个问题解决.下面把这两个方法都帖出来,请大家批评指正.或有更好的办法也帖出来,一起交流 第一种方法:            string sql = &qu ...

  9. CSS margin属性取值

    margin表示一个元素的外边距.取值为正值时,表示相对于正常流离邻近元素更远,而取负值时,使其更近 但是,设置margin后,四个方向的表现形式不同 自身发生移动:top.left margin-t ...

  10. CSS3-字体渐变色

    示例:Mauger`s Blog <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"& ...