POJ1273網絡流

//Edmonds_Karp
#include<iostream>
#include<queue>
using namespace std;
const int N=201;
const int INF=99999999;
int n,m,sum,s,t;//s,t爲始點和終點
int flow[N][N],cap[N][N],a[N],p[N];
//分別爲:flow[u][v]爲<u,v>流量、cap[u][v]爲<u,v>容量、a[i]表示源點s到節點i的路徑上的最小殘留量、p[i]記錄i的前驅
int min(int a,int b){return a<=b?a:b;}
void Edmonds_Karp(){
	int i,u,v;
	queue<int>q;//隊列,用bfs找增廣路
	while(1){
   		memset(a,0,sizeof(a));//每找一次,初始化一次
   		a[s]=INF;
   		q.push(s);//源點入隊
   		while(!q.empty()){
    		u=q.front();
    		q.pop();
    		for(v=1;v<=m;v++){
     			if(!a[v]&&flow[u][v]<cap[u][v]){
      				p[v]=u;
      				q.push(v);
      				a[v]=min(a[u],cap[u][v]-flow[u][v]);//s-v路徑上的最小殘量
     			}
    		}
   		}
   		if(a[m]==0)break;//找不到增廣路,則當前流已經是最大流    		
   		sum+=a[m];//流加上
   		for(i=m;i!=s;i=p[i]){// //從匯點順着這條增廣路往回走   
    		flow[p[i]][i]+=a[m];//更新正向流量
    		flow[i][p[i]]-=a[m];//更新反向流量
   		}
	}
	printf("%d\n",sum);
}
int main(){
	int v,u,w;
    while(scanf("%d%d",&n,&m)!=EOF){
   		s=1;//從1開始
   		t=m;//m爲匯點
   		sum=0;//記錄最大流量
  		memset(flow,0,sizeof(flow));//初始化
  		memset(cap,0,sizeof(cap));
   		while(n--){
    		scanf("%d%d%d",&u,&v,&w);
    		cap[u][v]+=w;//注意圖中可能出現相同的邊
   		}
   		Edmonds_Karp();
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章