sw算法求最小割学习
http:// blog.sina.com.cn/s/blog_700906660100v7vb.html
转载:http://www.cnblogs.com/ylfdrib/archive/2010/08/17/1801784.html
一个无向连通网络,去掉一个边集可以使其变成两个连通分量则这个边集就是割集;最小割集当然就权和最小的割集。
可以用最小切割最大流定理:
1.min=MAXINT,确定一个源点
2.枚举汇点
3.计算最大流,并确定当前源汇的最小割集,若比min小更新min
4.转到2直到枚举完毕
5.min即为所求输出min
不难看出复杂度很高:枚举汇点要O(n),最短增广路最大流算法求最大流是O((n^2)m)复杂度,在复杂网络中O(m)=O(n^2),算法总复杂度就是O(n^5);哪怕采用最高标号预进流算法求最大流O((n^2)(m^0.5)),算法总复杂度也要O(n^4)
所以用网络流算法求解最小割集复杂度不会低于O(n^4)。
---------
prim算法不仅仅可以求最小生成树,也可以求“最大生成树”。最小割集Stoer-Wagner算法就是典型的应用实例。
求解最小割集普遍采用Stoer-Wagner算法,不提供此算法证明和代码,只提供算法思路:
1.min=MAXINT,固定一个顶点P
2.从点P用“类似”prim的s算法扩展出“最大生成树”,记录最后扩展的顶点和最后扩展的边
3.计算最后扩展到的顶点的切割值(即与此顶点相连的所有边权和),若比min小更新min
4.合并最后扩展的那条边的两个端点为一个顶点(当然他们的边也要合并,这个好理解吧?)
5.转到2,合并N-1次后结束
6.min即为所求,输出min
prim本身复杂度是O(n^2),合并n-1次,算法复杂度即为O(n^3)
如果在prim中加堆优化,复杂度会降为O((n^2)logn)
这个Stoer-Wagner算法可以参见这篇paper(http://docs.google.com/fileview?id=0BwxLvD9mcDNtMjk3MWVkMTAtZjMzNi00ZWE3LTkxYjQtYTQwNzcyZTk3Njk2&hl=en), 其核心思想是迭代缩小规模, 算法基于这样一个事实:
对于图中任意两点s和t, 它们要么属于最小割的两个不同集中, 要么属于同一个集.
如果是后者, 那么合并s和t后并不影响最小割. 基于这么个思想, 如果每次能求出图中某两点之间的最小割, 然后更新答案后合并它们再继续求最小割, 就得到最终答案了. 算法步骤如下:
1. 设最小割cut=INF, 任选一个点s到集合A中, 定义W(A, p)为A中的所有点到A外一点p的权总和.
2. 对刚才选定的s, 更新W(A,p)(该值递增).
3. 选出A外一点p, 且W(A,p)最大的作为新的s, 若A!=G(V), 则继续2.
4. 把最后进入A的两点记为s和t, 用W(A,t)更新cut.
5. 新建顶点u, 边权w(u, v)=w(s, v)+w(t, v), 删除顶点s和t, 以及与它们相连的边.
6. 若|V|!=1则继续1.
看起来很简单, 每次像做最大生成树一样选最大"边"(注意, 这里其实不是边, 而是已经累计的权值之和, 就当是加权的度好了), 然后把最后进入的两个点缩到一块就可以了. 合并点最多有n-1次, 而不加堆优化的prim是O(n^2)的, 所以最终复杂度O(n^3), 要是你有心情敲一大坨代码, 还可以在稀疏图上用Fibonacci Heap优化一下, 不过网上转了一圈, 大多都是说能用Fibonacci
Heap优化到怎样怎样的复杂度, 真正能自己写出来的恐怕也没几个, 看看uoregon(俄勒冈大学)的一大坨代码就有点寒. (http://resnet.uoregon.edu/~gurney_j/jmpc/fib.html)
特别注意几个地方, 网上的好几个Stoer-Wagner版本都存在一些小错误:
1. 算法在做"最大生成树"时更新的不是普通意义上的最大边, 而是与之相连的边的权值和, 当所有边都是单位权值时就是累计度.
2. "最后进入A的两点记为s和t", 网上对s有两种解释, 一是在t之前一个加进去的点, 二是t的前趋节点, 也就是最后选择的那条边的另一端. 正解是第一种!
3. 对于稠密图, 比如这题, 我用堆, 映射二分堆, 或者STL的优先队列都会TLE, 还不如老老实实O(n^3).
另一篇论文:
最小割 Stoer-Wagner 算法
Etrnls 2007-4-15
Stoer-Wagner 算法用来求无向图 G=(V, E)的全局最小割。
算法基于这样一个定理:对于任意s, t V ∈ ,全局最小割或者等于原图的s-t 最小割,或者等于将原图进行 Contract(s,
t)操作所得的图的全局最小割。
算法框架:
1. 设当前找到的最小割MinCut 为+∞
2. 在 G中求出任意 s-t 最小割 c,MinCut = min(MinCut, c)
3. 对 G作 Contract(s, t)操作,得到 G'=(V', E'),若|V'| > 1,则G=G'并转 2,否则MinCut 为原图的全局最
小割
Contract 操作定义:
若不存在边(p, q),则定义边(p, q)权值w(p, q) = 0
Contract(a, b): 删掉点 a, b 及边(a, b),加入新节点 c,对于任意 v V ∈ ,w(v, c) = w(c, v) = w(a, v) + w(b,
v)
求 G=(V, E)中任意 s-t 最小割的算法:
定义w(A, x) = ∑w(v[i], x),v[i] A ∈
定义 Ax 为在x 前加入 A 的所有点的集合(不包括 x)
1. 令集合 A={a},a为 V中任意点
2. 选取 V - A中的 w(A, x)最大的点 x加入集合 A
3. 若|A|=|V|,结束
令倒数第二个加入 A的点为 s,最后一个加入 A的点为 t,则s-t 最小割为 w(At, t)
- #include <iostream>
- #include <stdio.h>
- #include <string.h>
- #include <queue>
- #define INT_MAX 0x3f3f3f3f
- using namespace std;
- int mp[502][502];
- int N,M;
- bool combine[502];
- int minC=INT_MAX;
- void search(int &s,int &t){
- bool vis[502];
- int w[502];
- memset(vis,0,sizeof(vis));
- memset(w,0,sizeof(w));
- int tmpj=1000;
- for(int i=0;i<N;i++){
- int max=-INT_MAX;
- for(int j=0;j<N;j++){
- if(!vis[j]&&!combine[j]&&max<w[j]){
- max=w[j];
- tmpj=j;
- }
- }
- if(t==tmpj){minC=w[t];return;}
- vis[tmpj]=1;
- s=t,t=tmpj;
- for(int j=0;j<N;j++){
- if(!vis[j]&&!combine[j])
- w[j]+=mp[t][j];
- }
- }
- minC=w[t];
- }
- int mincut(){
- int ans=INT_MAX;
- int s,t;
- memset(combine,0,sizeof(combine));
- for(int i=0;i<N-1;i++){
- s=t=-1;
- search(s,t);
- combine[t]=true;
- ans=ans>minC?minC:ans;
- for(int j=0;j<N;j++){
- mp[s][j]+=mp[t][j];
- mp[j][s]+=mp[j][t];
- }
- }
- return ans;
- }
- int main(){
- //freopen("in.txt","r",stdin);
- while(cin>>N>>M){
- memset(mp,0,sizeof(mp));
- int u,v,w;
- while(M--){
- scanf("%d %d %d",&u,&v,&w);
- mp[u][v]+=w;
- mp[v][u]+=w;
- }
- cout<<mincut()<<endl;
- }
- return 0;
- }
sw算法求最小割学习的更多相关文章
- SW算法求全局最小割(Stoer-Wagner算法)
我找到的唯一能看懂的题解:[ZZ]最小割集Stoer-Wagner算法 似乎是一个冷门算法,连oi-wiki上都没有,不过洛谷上竟然有它的模板题,并且2017百度之星的资格赛还考到了.于是来学习一下. ...
- poj 3469 Dual Core CPU【求最小割容量】
Dual Core CPU Time Limit: 15000MS Memory Limit: 131072K Total Submissions: 21453 Accepted: 9297 ...
- BZOJ_1001_狼抓兔子_(平面图求最小割+对偶图求最短路)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1001 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec ...
- HDU - 3035 War(对偶图求最小割+最短路)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3035 题意 给个图,求把s和t分开的最小割. 分析 实际顶点和边非常多,不能用最大流来求解.这道题要用 ...
- [ZJOI2011]最小割 & [CQOI2016]不同的最小割 分治求最小割
题面: [ZJOI2011]最小割 [CQOI2016]不同的最小割 题解: 其实这两道是同一道题.... 最小割是用的dinic,不同的最小割是用的isap 其实都是分治求最小割 简单讲讲思路吧 就 ...
- poj3565 Ants km算法求最小权完美匹配,浮点权值
/** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...
- 【POJ 2195】 Going Home(KM算法求最小权匹配)
[POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submiss ...
- USACO 4.4 Pollutant Control (网络流求最小割割集)
Pollutant ControlHal Burch It's your first day in Quality Control at Merry Milk Makers, and already ...
- Uvaoj 11248 Frequency Hopping(Dinic求最小割)
题意:1到n节点(节点之间有一定的容量),需要流过C的流量,问是否可以?如果可以输出possible, 否则如果可以扩大任意一条边的容量 可以达到目的,那么输出possible option:接着输出 ...
随机推荐
- JavaScript中bind、call、apply函数使用方法具体解释
在给我们项目组的其它程序介绍 js 的时候,我准备了非常多的内容,但看起来效果不大,果然光讲还是不行的,必须动手. 前几天有人问我关于代码里 call() 函数的使用方法.我让他去看书,这里推荐用js ...
- MySQL数据库表的数据插入、修改、删除、查询操作及实例应用
一.MySQL数据库表的数据插入.修改.删除和查询 CREATE DATABASE db0504; USE db0504; CREATE TABLE student ( sno ) NOT NULL ...
- 【NOIP 2004】 虫食算
[题目链接] https://www.luogu.org/problemnew/show/P1092 [算法] 搜索 + 剪枝 直接搜索显然会超时,考虑剪枝 1 : 优化搜索顺序 2 : 假设我们已经 ...
- java语言的运行机制
计算机高级编程语言按其程序的执行方式可分为编译型语言和解释型语言. 编译型语言是指使用专门的编译器,针对特定的操作系统将源程序代码一次性翻译成计算机能识别的机器指令.例如C.C++等都属于编译型语言. ...
- JUC集合-BlockingQueue
BlockingQueue 阻塞队列,支持两个附加操作. 1,在队列为空时,获取元素的线程会等待对列变为非空. 2,在队列为满时,存储元素的线程会等待对列可用. 使用场景: 生产者往对列里添加元素 消 ...
- aspnet_regiis加密文件提示路径中具有非法字符
加密结果受当前目录影响,不知道是不是哪里操作错误,mark. Web.config文件位置:E:\Web\Surgery 加密成功,上图命令最后有个".",表示web.conf ...
- 腾讯云TrustAsia DV SSL CA证书的申请及使用
1.证书申请及管理 对于已经拥有域名及公网服务器的用户,可以通过腾讯云申请TrustAsia DV SSL CA证书,证书申请流程包含填写基本信息和域名认证两步,非常清晰和简单,没有什么需要过 ...
- Postfix Self Expression
Postfix Self Expression A postfix self expression consists of an expression or the name of a type, i ...
- MindManager 2019新版上市 ,了解一下!
所有的等待都是值得的!MindManager在蓄力一年后,给各位思维导图爱好者带来了全新的MindManager 2019 for Windows.全新的版本包含英语.德语.法语.俄语.中文.日语,新 ...
- MongoDB 学习笔记(五):固定集合、GridFS文件系统与服务器端脚本
一.count.distinct与group 1.count函数:查询文档数,如下图: 2.distinct:去重,用法:db.runCommand({distinct:"集合名" ...