網絡流Edmonds_Karp (模板)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#define mem(a) memset(a,0,sizeof(a))
#define inf 999999999
using namespace std;
int c[210][210],f[210][210],p[210];
//f[u][v]爲<u,v>流量,c[u][v]爲<u,v>容量,p[i]記錄i的前驅
int s,t;//s爲源點,t爲匯點
int res[210];//res[i]表示源點s到節點i的路徑上的最小殘留量
int sum;//記錄最大流
int m,n;
void init(){
s=1;t=m;
sum=0;
mem(c);
mem(f);
mem(p);
}
void Edmonds_Karp(){
queue <int> q;
int u;
while(1){
memset(res,0,sizeof(res));//每找一次,初始化一次
res[s]=inf;
q.push(s);
while(!q.empty()){
u=q.front();
q.pop();
for(int i=1;i<=m;i++){
if(!res[i] && f[u][i]<c[u][i]){
p[i]=u;
q.push(i);
res[i]=min(res[u],c[u][i]-f[u][i]);//u-i路徑上的最小殘量
}
}
}
if(!res[t])break;//找不到增廣路,則當前流已經是最大流
sum+=res[t];
for(int i=t;i!=s;i=p[i]){//從匯點順着這條增廣路往回走
f[p[i]][i]+=res[t];//更新正向流量
f[i][p[i]]-=res[t];//更新反向流量
}
}
printf("%d\n",sum);
return ;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
init();
while(n--){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
c[x][y]+=z;//可能出現相同邊
}
Edmonds_Karp();
}
return 0;
}