POJ2914
POJ2914
无向图的最小割
题意:给你一个无向图,然后去掉其中的n条边,使之形成两个连通分量,也即原无向图不连通,求n的最小值。
输入:
m(无向图点集),n(无向图边集)
a,b,c(a,b两点之间流量)
输出:
n最小值
按照算法与实现上的Stoer-Wagner算法求解,原理不愿细究,知道接口能用就行,可以优化,用优先队列能将
无向图的最小割
题意:给你一个无向图,然后去掉其中的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; }