zoukankan      html  css  js  c++  java
  • P3376 【模板】网络最大流

       https://www.luogu.com.cn/problem/P3376

    #include<bits/stdc++.h>
    #define int long long
    const int INF = 0x3f3f3f3f;
    const int maxn = 3e5+10;
    using namespace std;
    int m,u,w,v;
    struct edge {
        int v, c, nxt;
    } e[maxn<<1];
    int s,t,n,head[maxn],q[maxn],level[maxn],tot;
    void add_edge(int u, int v, int c){
        e[tot] = (edge){ v, c, head[u] };
        head[u] = tot++;
    }
    //分层图
    bool BFS(){
        memset(level,0, sizeof(level));
        q[1] = s;
        level[s] = 1;
        int hd = 0,tl = 1;
        while (hd !=  tl){
            hd++;
            for(int i = head[q[hd]]; i != -1; i = e[i].nxt){
                if(e[i].c && !level[e[i].v]){
                    tl++;
                    level[e[i].v] = level[q[hd]] + 1;
                    q[tl] = e[i].v;
                    if (e[i].v == t)
                        return true;
                }
            }
        }
        return false;
    }
    
    //增广路
    int DFS(int f, int u){
        if (u == t)
            return f;
        int d = 0, used = 0;
        for (int i = head[u];i != -1;i = e[i].nxt){
            if (e[i].c && level[u] == level[e[i].v] - 1){
                if ((d = DFS(min(f - used, e[i].c), e[i].v))){
                    e[i].c -= d;
                    e[i ^ 1].c += d;//建立反向边
                    used += d;//这个点的最大流量
                }
            }
        }
        if (!used)
            level[u] = 0;
        return used;
    }
    int Dinic(){
        int max_flow = 0;
        while(BFS()){//判断汇点层次
            int d = 0;
            while ((d = DFS(INF, s)))
                max_flow += d;
        }
        return max_flow;
    }
    signed main(){
        //freopen("in","r",stdin);
        ios::sync_with_stdio(0);
        cin >> n >> m >> s >> t;
        memset(head, -1, sizeof(head));
        for (int i = 1; i <= m; i++){
            cin >> u >> v >> w;
            add_edge(u, v, w);
            add_edge(v, u, 0);//为什么是0?
        }
        cout << Dinic() << endl;
        return 0;
    }
    View Code

    1、裸的最大流

         2、二分图的最大匹配:建一个点S,连到二分图的集合A中;建一个点T,连到二分图的集合B中。再将所有的集合A中的点与集合B中的点相连。全部边权设为1,跑一遍最大流,结果即为二分图的最大匹配

         3、最小割:在单源单汇流量图中,最大流等于最小割

         4、求最大权闭合图:最大权值=正点权之和-最小割

     

    
    
  • 相关阅读:
    Django ajax 实现 loading 效果
    K8S service 简单介绍
    K8S Pod 生命周期 (二)
    异度之刃 Xenoblade 后感
    Nested Prefab Mode 嵌套预制体 保存问题 Dirty
    GIT速成
    Surface电池阈值
    如何删除通知栏无效图标(重置任务栏通知区域)
    Mouse For Winpad
    Re:LieF ~親愛なるあなたへ~ 后感
  • 原文地址:https://www.cnblogs.com/xcfxcf/p/12301656.html
Copyright © 2011-2022 走看看