[无向图大局最小割]zoj 2753:Min Cut (Destroy Trade Net)
[无向图全局最小割]zoj 2753:Min Cut (Destroy Trade Net)
大致题意:
给出一个无向图,求移除权值最少的边使得这个图被分为两个连通块。
大致思路:
裸的StoerWagner模版题,在神牛的博客瞎逛的时候看到了,就刷掉吧……希望不要降RP
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int nMax = 505; const int inf = 1<<30; int map[nMax][nMax]; int v[nMax], dis[nMax]; bool vis[nMax]; int StoerWagner(int n){ //点数从0开始 int i,j,res=inf; for(i=0;i<n;i++) v[i]=i; while(n>1){ int k=1,pre=0; for(i=1;i<n;i++){ dis[v[i]]=map[v[0]][v[i]]; if(dis[v[i]]>dis[v[k]]) k=i; } memset(vis,0,sizeof(vis)); vis[v[0]]=true; for(i=1;i<n;i++){ if(i==n-1){ res=min(res,dis[v[k]]); for(j=0;j<n;j++){ map[v[pre]][v[j]] += map[v[j]][v[k]]; map[v[j]][v[pre]] += map[v[j]][v[k]]; } v[k] = v[-- n]; } vis[v[k]] = true; pre = k; k = -1; for(j = 1; j < n; j ++) if(!vis[v[j]]){ dis[v[j]] += map[v[pre]][v[j]]; if(k == -1 || dis[v[k]] < dis[v[j]]) k = j; } } } return res; } int main(){ int n,m,u,v,w,s; while(scanf("%d%d",&n,&m)!=EOF){ memset(map,0,sizeof(map)); while(m--){ scanf("%d%d%d",&u,&v,&w); //u--;v--; map[u][v]+=w; map[v][u]+=w; } printf("%d\n",StoerWagner(n)); } return 0; }