题意:求全局最小割

不能用网络流求最小割,枚举举汇点要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. python 中的exec

    x = 10 expr = """ z = 30 sum = x + y + z print(sum) """ def func(): y ...

  2. linux shell中 if else for循环以及大于、小于、等于逻辑表达式的历程

    作者:邓聪聪 比如比较字符串.判断文件是否存在及是否可读等,通常用"[]"来表示条件测试. 注意:这里的空格很重要.要确保方括号的空格.笔者就曾因为空格缺少或位置不对,而浪费好多宝 ...

  3. 【转】C++标准转换运算符reinterpret_cast

    reinterpret_cast<new_type> (expression) reinterpret_cast运算符是用来处理无关类型之间的转换:它会产生一个新的值,这个值会有与原始参数 ...

  4. 029_mount bind挂载

    一. 由于公司的配置标准并不统一,交付的磁盘挂载的路径不是想要的路径,但是 1./home目录下有很重要的堡垒机登录的相关文件,还不能卸载 2.我通过pts/0登录的,这个文件描述符也是在/home目 ...

  5. nginx中Geoip_module模块的使用

    nginx中Geoip_module模块的使用 .安装模块,nginx也是通过yum安装 yum install nginx-module-geoip -y # 可以看到模块的链接库文件 [root@ ...

  6. 是armhf,还是armel?

    本文译至:https://blogs.oracle.com/jtc/entry/is_it_armhf_or_armel ARM处理器有各种品牌和规格,其中一部分的原因涉及到市场问题,成本,大小和功耗 ...

  7. Linux中给普通用户添加sudo权限

    使用Linux系统时,经常会被要求使用超级权限,但是root的权限太过大了,一般慎用!!!因此可以通过给普通用户添加sudo权限,平常用普通用户进行操作,当需要root权限的时候进行sudo操作.以下 ...

  8. Spring与Quartz实现定期任务

    <!-- 任务调度测试实现一 : 自定义的任务对象com.bocloud.equipment.test.ExampleJob 必须继承QuartzJobBean类,实现抽象方法executeIn ...

  9. Socket通讯成功案例

    Socket通讯案例 #region 服务端 //int port = 1234; //string host = "127.0.0.1"; //IPAddress ip = IP ...

  10. GitHub访问慢

    问题描述 一直都觉得访问 GitHub 时速度非常慢,刷新一下都要等好久!于是尝试一下能否解决掉... github.com assets-cdn.github.com avatar2.githubu ...