POJ2914

来源:互联网 发布:淘宝推广软件有用吗 编辑:程序博客网 时间:2024/06/18 09:29
POJ2914
无向图的最小割


题意:给你一个无向图,然后去掉其中的n条边,使之形成两个连通分量,也即原无向图不连通,求n的最小值。


输入:


m(无向图点集),n(无向图边集)
a,b,c(a,b两点之间流量)


输出:
n最小值


按照算法与实现上的Stoer-Wagner算法求解,原理不愿细究,知道接口能用就行,可以优化,用优先队列能将

复杂度减少到(nm+(n^2)*logn)

#include <iostream>#include <stdio.h>#include <string.h>using namespace std;const int max1=512;int g[max1][max1];int b[max1],dist[max1];int n,m;/*struct stoer_wagner{int n,g[max][max],b[max],dist[max];void init(int nn,int w[max][max]){int i,j;n=nn;for(int i=1;i<=n;i++){for(j=1;j<=n;j++)g[i][j]=w[i][j];}}*/int min_cut_phase(int ph,int &x,int &y){int i,j,t;b[t=1]=ph;for(i=1;i<=n;i++)if(b[i]!=ph)dist[i]=g[1][i];for(i=1;i<n;i++){x=t;for(t=0,j=1;j<=n;j++)if(b[j]!=ph&&(!t||dist[j]>dist[t]))t=j;b[t]=ph;for(j=1;j<=n;j++)if(b[j]!=ph)dist[j]+=g[t][j];}return y=t,dist[t];}void merge(int x,int y){int i;if(x>y) swap(x,y);for(i=1;i<=n;++i)if(i!=x&&i!=y)g[i][x]+=g[i][y],g[x][i]+=g[y][i];if(y==n)return ;for(i=1;i<n;++i) if(i!=y){swap(g[i][y],g[i][n]);swap(g[y][i],g[n][i]);}}void min_cut(){int ret=0x3fffffff,i,x,y;memset(b,0,sizeof(b));for(i=1;n>1;++i,n--){ret=min(ret,min_cut_phase(i,x,y));merge(x,y);}printf("%d\n",ret);}int main(){    while(scanf("%d%d",&n,&m)==2){        memset(g,0,sizeof(g));        while(m--){            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            a++,b++;            g[a][b]+=c;            g[b][a]+=c;        }min_cut();    }    return 0;}


0 0
原创粉丝点击