EK算法 模板 最大流(最小割)

1:最大流EK算法:复杂度:n*m^2(n是点数,m是边数)

2:如果遇到稠密图用Dinic

#include <bits/stdc++.h>
//最大流EK算法:复杂度:n*m^2(n是点数,m是边数)
//如果遇到稠密图用Dinic

using namespace std;
const int maxn=220,inf=0x7f7f7f7f;
int g[maxn][maxn],flow[maxn],pre[maxn],n,m;
queue<int> q;

inline int bfs(int s,int t)
{
    while(!q.empty())q.pop();
    memset(pre,-1,sizeof(pre));
    pre[s]=0,flow[s]=inf;
    q.push(s);
    while(!q.empty())
    {
        int p=q.front();q.pop();
        if(p==t)break;
        for(int u=1;u<=n;u++)
        {
            if(u!=s&&g[p][u]>0&&pre[u]==-1)
            {
                pre[u]=p;
                flow[u]=min(flow[p],g[p][u]);
                q.push(u);
            }
        }
    }
    if(pre[t]==-1)return -1;
    return flow[t];
}

inline int ek(int s,int t)
{
    int delta=0,tot=0;
    while(1)
    {
        delta=bfs(s,t);
        if(delta==-1)break;
        int p=t;
        while(p!=s)//更新增广路
        {
            g[pre[p]][p]-=delta;
            g[p][pre[p]]+=delta;
            p=pre[p];
        }
        tot+=delta;
    }
    return tot;
}

int main()
{
    ios::sync_with_stdio(0);
    int u,v,w;
    scanf("%d %d",&m,&n);
    memset(g,0,sizeof(g));
    memset(flow,0,sizeof(flow));
    for(int i=0;i<m;i++)
    {
        scanf("%d %d %d",&u,&v,&w);
        g[u][v]+=w;
    }
    printf("%d\n",ek(1,n));
    return 0;
}

/*
5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
50
*/
发布了164 篇原创文章 · 获赞 82 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/aiwo1376301646/article/details/104399878