POJ 2914 Minimum Cut 最小割集Stoer-Wagner算法(全局最小割)
来源:互联网 发布:吊杆控制台编程 编辑:程序博客网 时间:2024/05/20 00:53
题目大意:给一个无向图,任选两个不同的点作为源点和汇点做最小割,问所有最小割的最小值。
解题思路:解题什么都看这篇吧。传送门,我找了这么多中解释的比较好的。
但是网上还有一种代码量更少的思路,( 整体上是一样的,但是删点的时候处理方式不一样 )
我用的的是代码量较少的。
貌似这是道模板题,整个OJ就这么一道,
把模板掌握了应该就够用了..
我同样会把原思路中的代码贴在下面,
如果这种删点方式理解不了的话可以先看第二个模板。
(我就因为那个删点的马甲没理解以为我把算法理解错了,足足坑了两天)
算法框架:
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 <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <stack>using namespace std;#define FOR(i,l,r) for(int i=(l);i<=(r);++i)#define REP(i,n) for(int i=0;i<(n);++i)#define DSC(i,r,l) for(int i=(r);i>=(l);--i)#define N 510int map[N][N];int sum[N];//记录w(A,i)int v[N]; //给每个点装个马甲,在删点的时候用bool visit[N];//标记是否加入了A集合int solve(int n){ int ans=1e9; REP(i,n) v[i]=i; //最开始每个马甲初始化为自身 while(n>1) { memset(visit,0,sizeof(visit)); memset(sum,0,sizeof(sum)); int k,pre=0; for(int i=1;i<n;i++) { k=-1; for(int j=1;j<n;j++) if(!visit[v[j]]) { sum[v[j]]+=map[v[pre]][v[j]]; if(k==-1 || sum[v[k]]<sum[v[j]]) k=j; //选择出最大的w(A,v[j]) } visit[v[k]]=1;//把v[k]只想的点加入A集合 //在循环的过程中马甲会变化,v[k]不一定是指向k的 if(i==n-1) break; pre=k; } ans=min(ans,sum[v[k]]); if(ans==0) return 0; REP(j,n) map[v[j]][v[pre]]=map[v[pre]][v[j]]+=map[v[k]][v[j]]; v[k]=v[--n]; //这就是这道题为什么要用马甲的地方 //你需要删掉的是k点,并且总点数要减一 //所以你就把马甲披在了第n-1个点上,而因为--n了,以后的循环便不会直接循环到第n-1个点 //而是通过v[k]来访问第n-1个点,同时删掉了k点 } return ans;}int main(){ int n,m,x,y,c; while(cin>>n>>m) { memset(map,0,sizeof(map)); while(m--) { scanf("%d%d%d",&x,&y,&c); map[x][y]+=c; map[y][x]+=c; } cout<<solve(n)<<endl; } return 0;}
接下来来一发正常的删点的模板,来自 路竹
#include<cstdio>#include<cstring>#include<climits>const int N = 501;int n,mat[N][N],del[N],vis[N],dist[N];int S,T;int search(int tn){//T表征最后一个扩展进最大生成树的点,S是倒数第二个int i,j,tmp,max,cut;T=S=-1;memset(vis,0,sizeof(vis));memset(dist,0,sizeof(dist));//最大生成树for(i=0;i<=n-tn;i++){max=-1;for(j=0;j<n;j++){if(!vis[j] && !del[j] && dist[j]>max)max=dist[j], tmp=j;}S=T; T=tmp;cut=max;vis[T]=1;for(j=0;j<n;j++){if(!vis[j] && !del[j])dist[j]+=mat[T][j];}}return cut;}int Stoer_Wagner(){int ans=INT_MAX;memset(del,0,sizeof(del));for(int i=1;i<n;i++){//i 表征搜索次数,i越大图中剩余的点越少,自然搜索次数越少 int cut=search(i);if(cut<ans)ans=cut;if(ans==0)return 0;//图不连通时最小割为0del[T]=1;for(int j=0;j<n;j++){//S,T合并if(!del[j])mat[S][j]=mat[j][S]+=mat[T][j];}}return ans;}int main(){int a,b,c,m;while(~scanf("%d%d",&n,&m)){memset(mat,0,sizeof(mat));while(m--){scanf("%d%d%d",&a,&b,&c);mat[a][b]=mat[b][a]+=c;}int ans=Stoer_Wagner();printf("%d\n",ans);}return 0;}
- POJ 2914 Minimum Cut 最小割集Stoer-Wagner算法(全局最小割)
- POJ 2914 Minimum Cut Stoer-Wagner(全局最小割)
- poj 2914 Minimum Cut 【无向图全局最小割 Stoer-wagner算法】
- POJ_P2914 Minimum Cut(Stoer-Wagner算法 全局最小割)
- poj 2914 Minimum Cut(无向图最小割 Stoer-Wagner算法)
- POJ2914 Minimum Cut 【全局最小割Stoer-Wagner模板题】
- 全局最小割集Stoer-Wagner算法
- poj 2914 Minimum Cut 求无向图的最小割 Stoer-Wagner算法模板
- 无向带权图最小割stoer-wagner算法(poj 2914 Minimum cut)
- poj 2914 最小割 Stoer-Wagner 算法
- POJ 2914 Minimum Cut(求全图的最小割Stoer-Wagner)
- Stoer-Wagner算法(最小割集)
- poj 2914 全局最小割 stoer wagner算法 最小割模板
- Stoer-Wagner算法求全局最小割
- poj2914(stoer-wagner算法求解全局最小割)
- 最小割 Stoer-Wagner 算法
- 最小割集Stoer-Wagner算法【ZZ】
- 最小割集Stoer-Wagner算法
- 断点调试
- [Paper Study] Fundamentals in Spike Response Model and SpikeProp
- 分享30个独特的 404 错误页面设计模板
- C#关键字var的简要说明
- oracle数据库的5种约束类型
- POJ 2914 Minimum Cut 最小割集Stoer-Wagner算法(全局最小割)
- 《jQuery权威指南》学习笔记之第2章 jQuery选择器
- Using FANN and its Python bindings to construct neural networks
- 北邮校长方滨兴将离职 临别奉送学生“六好”锦囊
- 产品经理常犯的七大错误
- setup virtual box extention for lubuntu
- 2013春季学期总结
- 解决cisvc.exe占用CPU
- 创建关闭进程