最大流——EK算法

    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;
}

猜你喜欢

转载自blog.csdn.net/qq_39759315/article/details/86140390