hdu3691(无向图最小割的求解)
生活随笔
收集整理的這篇文章主要介紹了
hdu3691(无向图最小割的求解)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
給出一個無向圖的源點和每個邊的容量,讓你自己選擇匯點,使得最大流最小,輸出最大流。
思路:
用SW算法求一遍無向圖的最小割即可,源點如果在S集合中,我們只要在T集合中隨便找一個點當作匯點就可以得到想要的最大流,反之亦然。
代碼:
#include<cstdio> #include<cstring> #include<iostream> #include<cstring> #include<cstdlib> #include<cmath> #include<string> #include<queue> #include<vector> #include<map> #include<stack> #include<climits> #include<sstream> #include<algorithm>using namespace std;const int maxn=500;int ww[maxn][maxn]; struct SW{int n,g[maxn][maxn],b[maxn],dist[maxn];void init(int nn,int w[maxn][maxn]){int i,j;n=nn;for(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[i][y];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]);}}int Min_Cut(){int i,ret=0x3fffffff,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);}return ret;} };int main() {int n,m,src;while(scanf("%d%d%d",&n,&m,&src)!=EOF){if(!n&&!m&&!src)return 0;SW t;memset(ww,0,sizeof ww);for(int i=1;i<=m;i++){int u,v,x;scanf("%d%d%d",&u,&v,&x);ww[u][v]+=x;ww[v][u]+=x;}t.init(n,ww);printf("%d\n",t.Min_Cut());}return 0; }總結
以上是生活随笔為你收集整理的hdu3691(无向图最小割的求解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu5373(整除11)
- 下一篇: hdu3694(四边形的费马点)