网络流 EK算法模板。

这篇博客讲得很好

#include<queue>
#include<stdio.h>
#include<string.h>
using namespace std;
const int MAXN=205;
const int INF=0x3f3f3f3f;
int r[MAXN][MAXN];
bool vis[MAXN];
int pre[MAXN];
int m,n;
bool bfs(int s,int t)
{
    int p;
    memset(pre,-1,sizeof(pre));
    memset(vis,false,sizeof(vis));
    queue<int>q;
    pre[s]=s;//存储路径,即增广路。
    vis[s]=true;
    q.push(s);
    while(!q.empty())
    {
        p=q.front();
        q.pop();
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&r[p][i]>0)//结点是否访问过,以及该边否有剩余流量。
            {
                vis[i]=true;
                pre[i]=p;//i结点的上一个结点
                if(i==t)
                    return true;
                q.push(i);
            }
        }
    }
    return false;
}
int EK(int s,int t)
{
    int flow=0,d;
    while(bfs(s,t))
    {
        d=INF;
        for(int i=t;i!=s;i=pre[i])
            d=d<r[pre[i]][i]?d:r[pre[i]][i];//找到该路径上容量最小的边。
        for(int i=t;i!=s;i=pre[i])
        {
            r[pre[i]][i]-=d;//减去正向的容量,
            r[i][pre[i]]+=d;//在负向上加上流量,
        }
        flow+=d;
    }
    return flow;
}
int main()
{
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        int s,e,c;//s->e,容量为c;
        memset(r,0,sizeof(r));
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&s,&e,&c);
            r[s][e]+=c;
        }
        printf("%d\n",EK(1,n));
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39576425/article/details/79577036