您的位置:首页 > 其它

poj-2914-全局最小割

2017-06-06 18:13 381 查看
https://vjudge.net/problem/POJ-2914

全局最小割就是对于这个图枚举任意 s和t,求其最小割,然后在取最小的最小割,即为全局最小割。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
const int maxn = 550;
const int inf = 1000000000;
int n,r;
int edge[maxn][maxn],dist[maxn];
bool vis[maxn], bin[maxn];
void init()
{
memset(edge, 0, sizeof(edge));
memset(bin, false, sizeof(bin));
}
int contract( int &s, int &t )          // 寻找 s,t
{
memset(dist, 0, sizeof(dist));
memset(vis, false, sizeof(vis));
int i, j, k, mincut, maxc;
for(i = 1; i <=n; i++)
{
k = -1; maxc = -1;
for(j = 1; j <=n; j++)if(!bin[j] && !vis[j] && dist[j] > maxc)
{
k = j;  maxc = dist[j];
}
if(k == -1)return mincut;
s = t;  t = k;
mincut = maxc;
vis[k] = true;
for(j = 1; j <=n; j++)if(!bin[j] && !vis[j])
dist[j] += edge[k][j];
}
return mincut;
}
int Stoer_Wagner()
{
int mincut, i, j, s, t, ans;
for(mincut = 1e8+5, i = 1; i <n; i++)
{
ans = contract( s, t );
bin[t] = true;
if(mincut > ans)mincut = ans;
if(mincut == 0)return 0;
for(j = 1; j <=n; j++)if(!bin[j])
edge[s][j] = (edge[j][s] += edge[j][t]);
}
return mincut;
}
int main()
{    int m;
int a,b,c;
while(cin>>n>>m)
{   init();
//memset(edge,0,sizeof(edge));
for(int i=1;i<=m;i++)
{scanf("%d%d%d",&a,&b,&c);
edge[a+1][b+1]+=c;
edge[b+1][a+1]+=c;
}
cout<<Stoer_Wagner()<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: