EK算法是求最大流的一种容易实现、代码易懂的算法。
EK算法仍然是一个基于增广路的算法,思路非常简单。每次从S尝试找到一条到达T的路径,路径上最小的残留量大于0,那么我们就可以把这条路上的最小残留量减去,累加到ans里。继续bfs直到找不到位置,此时ans就是最大流。
EK增广路算法的时间复杂度为O(nm^2)。但是在实际运营中远远达不到这个上界,效率较高,一般认为,可以处理10^3~10^4内规模的网络。
//??????EK??
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int inf=1<<29,N=2010,M=20010;
int n,m,s,t,tot,maxflow,ver[M],edge[M],Next[M],v[N],lin[N],incf[N],pre[N];
using namespace std;
void add(int x,int y,int c){
ver[++tot]=y;Next[tot]=lin[x];edge[tot]=c;lin[x]=tot;
ver[++tot]=x;Next[tot]=lin[y];edge[tot]=0;lin[y]=tot;
}
bool bfs(){
memset(v,0,sizeof(v));
queue<int>q;
q.push(s),v[s]=1;
incf[s]=inf;
while(q.size()){
int x=q.front();q.pop();
for(int i=lin[x];i;i=Next[i]){
if(edge[i]){
int y=ver[i];
if(v[y]) continue;
incf[y]=min(incf[x],edge[i]);
pre[y]=i;
q.push(y),v[y]=1;
if(y==t) return 1;
}
}
}
return 0;
}
void update(){
int x=t;
while(x!=s){
int i=pre[x];
edge[i]-=incf[t];
edge[i^1]+=incf[t];
x=ver[i^1];
}
maxflow+=incf[t];
}
int main(){
while(cin>>n>>m){
memset(lin,0,sizeof(lin));
s=1,t=n;tot=1,maxflow=0;
for(int i=1;i<=m;++i){
int x,y,c;scanf("%d%d%d",&x,&y,&c);
add(x,y,c);
}
while(bfs()) update();
printf("%d\n",maxflow);
}
return 0;
}