zoukankan      html  css  js  c++  java
  • 最大流的EK算法模板

    模板题:洛谷p3376

    题目大意:

    给出一个网络图,以及其源点和汇点,求出其网络最大流。

    基本思路:

    套模板

    EK的时间复杂度O(V*E^2)

    EK算法思路: 
    1.通过BFS拓展合法节点(每个节点在本次BFS中仅遍历一次),找到汇点,并记录每个节点的前面节点(pre)(若找不到增广路,算法结束) 
    2.通过BFS的记录,从汇点回溯回源点,记录下每条弧流量的**最小值**minn, ans += minn(否则就会超出某条边的限制流量) 
    3.将所有经过的边的流量减去minn,反向边加上minn 
    4.重复上述步骤,直到找不到增广路,算法结束。

    代码如下:

    #include<iostream>
    #include<string>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    
    using namespace std;
    
    typedef long long ll;
    const int inf = 0x3f3f3f3f;
    const int maxn =10000+10;
    int n,m,st,en;
    struct Flow{
        int st,en,num;
    }flow[200000+10];
    vector<int>gra[maxn];
    bool vis[maxn];
    int pre[maxn];
    bool bfs(){
        memset(vis,false,sizeof(vis));
        vis[st]=true;
        queue<int>q;
        q.push(st);
        while(!q.empty()){
            int qf=q.front();
            q.pop();
            int sz=gra[qf].size();
            for(int i=0;i<sz;i++){
                int id=gra[qf][i];
                int v=flow[id].en;
                if(flow[id].num>0&&!vis[v]){
                    vis[v]=true;
                    q.push(v);
                    pre[v]=id;
                    if(v==en){
                        return true;
                    }
                }
            }
        }
        return false;
    }
    int EK(){
        int max_flow=0;
        while(bfs()){
            int _min=inf;
            for(int i=en;i!=st;i=flow[pre[i]].st){
                _min=min(_min,flow[pre[i]].num);
            }
            for(int i=en;i!=st;i=flow[pre[i]].st){
                flow[pre[i]].num-=_min;
                flow[pre[i]+m].num+=_min;
            }
            max_flow+=_min;
        }
        return max_flow;
    }
    int main(){
        scanf("%d%d%d%d",&n,&m,&st,&en);
        for(int i=0;i<m;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            flow[i].st=u;
            flow[i].en=v;
            flow[i].num=w;
            flow[i+m].st=v;
            flow[i+m].en=u;
            flow[i+m].num=0;
            gra[u].push_back(i);
            gra[v].push_back(i+m);
        }
        printf("%d
    ",EK());
        return 0;
    }
  • 相关阅读:
    Linux运维系列一 CentOS 7桌面系统加入到Samba4 AD域环境中
    Django 系列一 (创建第一个工程)
    提高运维效率(二)桌面显示IP
    提高运维效率(一)远程管理
    python group()
    【原创】我所理解的资源加载方式
    【原创】我所理解的自动更新-知识点讲解
    【原创】我所理解的自动更新-客户端更新流程
    【原创】我所理解的自动更新-资源打包流程
    【原创】我所理解的自动更新-APP发布与后台发布
  • 原文地址:https://www.cnblogs.com/imzscilovecode/p/8724078.html
Copyright © 2011-2022 走看看