图论 最小割Toer-Wagner算法
来源:互联网 发布:golang http basicauth 编辑:程序博客网 时间:2024/06/11 14:28
参考来源:http://blog.sina.com.cn/s/blog_700906660100v7vb.html
这里讨论无向联通图全局最小割
方法一 因为两点的最小割其实就是最大流,所以我们可以用dinic算法,枚举源点与汇点, 枚举时间复杂度O(n^2) , Dinic算法 时间复杂度O(n^2m),总的时间复杂度O(N^4M),显然当n很大的时候,需要的时间特别大,
方法二 Toer-Wagner算法,这个算法的正确性此处不证明,.核心的思想就是借鉴Prim算法,扩展最大生成树,记录最后加入的两个点
这里先定义两个操作,:
1.对于图G(V,E) , 对于V的一个子集A, i 属于 V-A , W[i] = 子集A中所有的点到 i 的直接距离之和(这里的直接距离,是指两点直接相连的距离,不借助其它点)
2. Unite(s,t) 合并两个点,将 t 点合并到 s 点中, 所有到 s 的 点的距离 加上到t的, s到其它点的距离 加上t到其他点的距离 (这些只处理指直接相连的点的距离)
用一张图说明合并操作
此时合并5,6点
算法流程如下
1.A代表点的集合,初始为空 , W[i] = 0;
2. n-1 次循环
令集合A={a},a为V中任意点
遍历所有的点,求出V-A中的w[i] ,
将最大的点 i加入集合A中
直到所有点都加入集合A后, 记录最后加入的为 t , 倒数第二个加入的为 s ,合并 s , t
3 . 最小割为每次循环的w[t] 中的最小值
下面详细说明求s,t的过程 ,以Poj (pku) 2914 Minimum Cut的第三个case为例,图为
G(V,E)
我们设法维护这样的一个w[],初始化为0;
我们把V-A中的点中w[i]最大的点找出来加入A集合;
V-A直到为空
w[]的情况如下
w[i]
0
1
2
3
4
5
6
7
初始值
0
0
0
0
0
0
0
0
A=A∪{0}
---
1
1
1
1
0
0
0
A=A∪{1}
---
2
2
1
0
0
0
A=A∪{2}
---
3
1
0
0
0
A=A∪{3}
---
1
0
0
1
A=A∪{4}
---
1
1
2
A=A∪{7}
2
2
---
A=A∪{5}
---
3
A=A∪{6}
---
上图一行一行的计算, 第三行, A中加入0点后, V-A 到A的w[i] , 如果有大小相同的,加入第一次出现的,即加入1点,
第四行, 加入1点后, 到A 的w[i] ,再从中取一个最大的,把点2加入A,
........
记录最后加入A的节点为t=6,倒数第二个加入A的为s=5,则s-t的最小割就为w[s],在图中体现出来的意思就是5-6的最小割为w[s]=3
然后我们合并 s ,t ,得到下图
G(V’,E’)
重复上述操作
w[i]
0
1
2
3
4
5
7
初始值
0
0
0
0
0
0
0
A=A∪{0}
---
1
1
1
1
0
0
A=A∪{1}
---
2
2
1
0
0
A=A∪{2}
---
3
1
0
0
A=A∪{3}
---
1
0
1
A=A∪{4}
---
2
2
A=A∪{5}
---
4
A=A∪{7}
---
s=5,t=7
合并5 ,7 得到
w[i]
0
1
2
3
4
5
初始值
0
0
0
0
0
0
A=A∪{0}
---
1
1
1
1
0
A=A∪{1}
---
2
2
1
0
A=A∪{2}
---
3
1
0
A=A∪{3}
---
1
1
A=A∪{4}
---
4
A=A∪{5}
---
s=4,t=5
合并4 ,5 得到
w[i]
0
1
2
3
4
初始值
0
0
0
0
0
A=A∪{0}
---
1
1
1
1
A=A∪{1}
---
2
2
1
A=A∪{2}
---
3
1
A=A∪{3}
---
2
A=A∪{4}
---
s=3,t=4
一直循环N-1次,全局最小割即每次的W[t]中最小的
代码如下:
/* * 全局最小割Stoer-Wagner算法 * 时间复杂度O(n^3) , 求s,t的时候可以优化到nlogn , 总体 O(n^2logn),此处不优化 * 从0开始标号 * 无向联通图的最小割 */const int SIZE = 520;int graph[SIZE][SIZE];bool ISCombine[SIZE];bool ISvis[SIZE];int W[SIZE];int N,M;//合并两个点,将 t 并入 sinline void _unite( int s ,int t){ ISCombine[t] = true; for (int i = 0;i < N;++i){ graph[s][i] += graph[t][i]; graph[i][s] += graph[i][t]; }}//寻找最大的W[i] , 并记录最后两个s,t下标int _SearchMaxWi( int &s, int &t ){ memset( ISvis , 0 , sizeof(ISvis) ); memset( W , 0 , sizeof(W) ); int tmpj = 1000; for (int i = 0;i < N;++i ) { int MAX = INT_MIN; for (int j = 0;j < N ; ++j) if ( !ISCombine[j] && !ISvis[j] && W[j] > MAX ) MAX = W[j] , tmpj = j; if(t == tmpj) return W[t]; ISvis[tmpj] = true; s = t , t = tmpj; for (int j = 0;j < N;j++) if ( !ISvis[j] && !ISCombine[j] ) W[j] += graph[t][j]; } return W[t];}int Stoer_Wagner(){ memset(ISCombine , 0, sizeof(ISCombine)); int ans = INT_MAX; int s,t; for (int i = 0;i < N-1;++i ){ s = t = -1; int tmp = _SearchMaxWi(s,t); //cout <<s<<" "<<t<<endl; ans = min(ans, tmp); //用每次的W[i]更新ans _unite(s,t); //合并s,t } return ans;}
- 图论 最小割Toer-Wagner算法
- 最小割 Stoer-Wagner 算法
- 最小割集Stoer-Wagner算法【ZZ】
- 最小割集Stoer-Wagner算法
- 最小割集Stoer-Wagner算法
- 最小割集Stoer-Wagner算法
- 最小割集Stoer-Wagner算法
- 最小割Stoer-Wagner算法模板hdu3691
- Stoer-Wagner算法求全局最小割
- poj 2914 最小割 Stoer-Wagner 算法
- 全局最小割集Stoer-Wagner算法
- Stoer-Wagner算法(最小割集)
- 最小割集Stoer-Wagner算法,网络最大流问题
- POJ2914无向图最小割Stoer-Wagner算法
- poj 2914 无向图最小割 Stoer-Wagner算法
- poj 2914(无向图最小割Stoer-Wagner算法)
- 全局最小割Stoer-Wagner算法 时间复杂度(o^3)
- POJ_P2914 Minimum Cut(Stoer-Wagner算法 全局最小割)
- ajax动态加载评论,jquery操作dom实时显示自己的评论
- ActivityOptionsCompat--Material Designer的低版本兼容实现
- linux下df -hT和du -sh 显示的数据非常不一致解决方法
- HTML个人设置中心以头像为背景类似蒙层效果
- Ruby安装
- 图论 最小割Toer-Wagner算法
- Ubuntu 下安装Beyond Compare
- Java类和对象的概念
- Android6.0中有关权限的那些坑资料的整理
- java枚举
- 文件操作汇总
- 在亚马逊云服务器上部署阿里数据库Otter(三)
- nasm on android
- .ssh目录里什么时候需要authorized_keys