POJ 2914 Minimum Cut (全局最小割)

【题目链接】 http://poj.org/problem?id=2914

【题目大意】

  求出一个最小边割集,使得图不连通

【题解】

  利用stoerwagner算法直接求出全局最小割,即答案。

【代码(递归)】

#include <cstdio>
#include <algorithm>
#include <cstring> 
using namespace std;
const int INF=0x3f3f3f3f;
const int MAX_N=510;
int v[MAX_N],w[MAX_N],c[MAX_N],g[MAX_N][MAX_N],S,T,now,N,M,x,y,z;
void search(){
    int i,j,k,t;
    for(i=0;i<N;i++)v[i]=w[i]=0;
    for(S=T=-1,i=0;i<N;i++){
        for(k=-INF,j=0;j<N;j++)if(!c[j]&&!v[j]&&w[j]>k)k=w[t=j];
        if(T==t)return;
        S=T,T=t,now=k,v[t]=1;
        for(j=0;j<N;j++)if(!c[j]&&!v[j])w[j]+=g[t][j];
    }
}
int stoerwagner(){
    int i,j,ans=INF;
    for(i=0;i<N;i++)c[i]=0;
    for(i=0;i<N-1;i++){
        search();
        if(now<ans)ans=now;
        if(ans==0)return 0;
        for(c[T]=1,j=0;j<N;j++)if(!c[j])g[S][j]+=g[T][j],g[j][S]+=g[j][T];
    }return ans;
}
void init(){
    memset(g,0,sizeof(g));
    while(M--)scanf("%d%d%d",&x,&y,&z),g[x][y]+=z,g[y][x]+=z;
}
void solve(){
    printf("%d
",stoerwagner());
}
int main(){
    while(~scanf("%d%d",&N,&M)){
        init();
        solve();
    }return 0;
}

【代码(非递归)】

#include <cstdio>
#include <algorithm>
#include <cstring> 
using namespace std;
const int INF=0x3f3f3f3f;
const int MAX_N=510;
int G[MAX_N][MAX_N],v[MAX_N],f[MAX_N],N,M,vis[MAX_N];
int Stoer_Wagner(){
    int ret=INF;
    for(int i=1;i<=N;i++)v[i]=i;
    while(N>1){
        int k,lst=v[1];
        memset(vis,0,sizeof(vis));
        memset(f,0,sizeof(f));
        vis[v[1]]=1;
        for(int i=2;i<=N;i++){
            k=1;
            for(int j=2;j<=N;j++)if(!vis[v[j]]&&(f[v[j]]+=G[lst][v[j]])>f[v[k]])k=j;
            vis[v[k]]=1;
            if(i<N)lst=v[k];
        }ret=min(ret,f[v[k]]);
        for(int j=1;j<=N;j++)G[v[j]][lst]=G[lst][v[j]]=G[lst][v[j]]+G[v[k]][v[j]];
        v[k]=v[N--];
    }return ret;
}
void init(){
    memset(G,0,sizeof(G));
	for(int i=1;i<=M;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        ++x;++y;
        G[x][y]+=z;G[y][x]+=z;
    }
}
void solve(){printf("%d
",Stoer_Wagner());}
int main(){
    while(~scanf("%d%d",&N,&M)){
        init();
        solve();
    }return 0;
}
原文地址:https://www.cnblogs.com/forever97/p/poj2914.html