• 有源汇有上下界最大/最小流


    建图还是要想一想的...写一下吧

    首先根据有源汇可行流建图,正向附加边满流证明有可行流

    然后在这个残量网络上删掉 $(t,s,oo)$ 这条边,跑 $s->t$ 最大流就是最大流,$t->s$ 最大流就是最小流

    #include <bits/stdc++.h>
    #define int long long
    #define LL long long
    #define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
    #define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
    using namespace std;
    inline int read() {
        int x = 0, f = 1;
        char ch;
        for (ch = getchar(); !isdigit(ch); ch = getchar())
            if (ch == '-')
                f = -f;
        for (; isdigit(ch); ch = getchar()) x = 10 * x + ch - '0';
        return x * f;
    }
    const int maxn = 500010;
    struct Dinic {
    #define oo 21474832333333LL
        int n, m, s, t;
        int cur[maxn], head[maxn], nx[maxn];
        struct Edge {
            int from, to, caps;
            Edge() {}
            Edge(int _1, int _2, int _3) : from(_1), to(_2), caps(_3) {}
        } es[maxn];
        void add(int u, int v, int w) {
            es[m] = Edge(u, v, w);
            nx[m] = head[u];
            head[u] = m++;
            es[m] = Edge(v, u, 0);
            nx[m] = head[v];
            head[v] = m++;
        }
        Dinic() {
            m = 0;
            memset(head, -1, sizeof(head));
        }
        queue<int> q;
        int dis[maxn];
        int BFS() {
            for (int i = 0; i <= n; i++) dis[i] = 0;
            dis[t] = 1;
            q.push(t);
            while (!q.empty()) {
                int now = q.front();
                q.pop();
                for (int i = head[now]; i != -1; i = nx[i]) {
                    Edge &e = es[i ^ 1];
                    if (!dis[e.from] && e.caps) {
                        dis[e.from] = dis[now] + 1;
                        q.push(e.from);
                    }
                }
            }
            return (dis[s] > 1);
        }
        int DFS(int u, int a) {
            if (u == t || !a)
                return a;
            int flow = 0, f;
            for (int &i = cur[u]; i != -1; i = nx[i]) {
                Edge &e = es[i];
                if (dis[e.to] == dis[u] - 1 && (f = DFS(e.to, min(e.caps, a)))) {
                    flow += f;
                    a -= f;
                    e.caps -= f;
                    es[i ^ 1].caps += f;
                    if (a == 0)
                        return flow;
                }
            }
            return flow;
        }
        int MaxFlow(int _s, int _t) {
            s = _s, t = _t;
            int flow = 0, f;
            while (BFS()) {
                for (int i = 0; i <= n; i++) cur[i] = head[i];
                while (f = DFS(s, oo)) flow += f;
            }
            return flow;
        }
    } sol;
    int ind[maxn];
    signed main() {
        int n = read(), m = read(), s = read(), t = read(), SS = n + 1, TT = n + 2;
        for (int i = 1; i <= m; i++) {
            int u = read(), v = read(), b = read(), a = read();
            sol.add(u, v, a - b); ind[v] += b; ind[u] -= b;
        } sol.n = n + 5;
        int totflow = 0;
        rep(u, 1, n) {
            if(ind[u] > 0) sol.add(SS, u, ind[u]), totflow += ind[u];
            if(ind[u] < 0) sol.add(u, TT, -ind[u]);
        }
        sol.add(t, s, oo);
        int rflow = sol.MaxFlow(SS, TT);
        if(totflow > rflow) {
            cout << "please go home to sleep" << endl;
            return 0;
        } sol.es[m - 1].caps = sol.es[m - 2].caps = 0;
        cout << oo - sol.MaxFlow(t, s) << endl;
    }
    最小流
    #include <bits/stdc++.h>
    #define int long long
    #define LL long long
    #define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
    #define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
    using namespace std;
    inline int read() {
        int x = 0, f = 1;
        char ch;
        for (ch = getchar(); !isdigit(ch); ch = getchar())
            if (ch == '-')
                f = -f;
        for (; isdigit(ch); ch = getchar()) x = 10 * x + ch - '0';
        return x * f;
    }
    const int maxn = 200010;
    struct Dinic {
    #define oo 21474832333333LL
        int n, m, s, t;
        int cur[maxn], head[maxn], nx[maxn];
        struct Edge {
            int from, to, caps;
            Edge() {}
            Edge(int _1, int _2, int _3) : from(_1), to(_2), caps(_3) {}
        } es[maxn];
        void add(int u, int v, int w) {
            es[m] = Edge(u, v, w);
            nx[m] = head[u];
            head[u] = m++;
            es[m] = Edge(v, u, 0);
            nx[m] = head[v];
            head[v] = m++;
        }
        Dinic() {
            m = 0;
            memset(head, -1, sizeof(head));
        }
        queue<int> q;
        int dis[maxn];
        int BFS() {
            for (int i = 0; i <= n; i++) dis[i] = 0;
            dis[t] = 1;
            q.push(t);
            while (!q.empty()) {
                int now = q.front();
                q.pop();
                for (int i = head[now]; i != -1; i = nx[i]) {
                    Edge &e = es[i ^ 1];
                    if (!dis[e.from] && e.caps) {
                        dis[e.from] = dis[now] + 1;
                        q.push(e.from);
                    }
                }
            }
            return (dis[s] > 1);
        }
        int DFS(int u, int a) {
            if (u == t || !a)
                return a;
            int flow = 0, f;
            for (int &i = cur[u]; i != -1; i = nx[i]) {
                Edge &e = es[i];
                if (dis[e.to] == dis[u] - 1 && (f = DFS(e.to, min(e.caps, a)))) {
                    flow += f;
                    a -= f;
                    e.caps -= f;
                    es[i ^ 1].caps += f;
                    if (a == 0)
                        return flow;
                }
            }
            return flow;
        }
        int MaxFlow(int _s, int _t) {
            s = _s, t = _t;
            int flow = 0, f;
            while (BFS()) {
                for (int i = 0; i <= n; i++) cur[i] = head[i];
                while (f = DFS(s, oo)) flow += f;
            }
            return flow;
        }
    } sol;
    int ind[maxn];
    signed main() {
        int n = read(), m = read(), s = read(), t = read(), SS = n + 1, TT = n + 2;
        for (int i = 1; i <= m; i++) {
            int u = read(), v = read(), b = read(), a = read();
            sol.add(u, v, a - b);
            ind[v] += b;
            ind[u] -= b;
        }
        sol.n = n + 5;
        int totflow = 0;
        rep(u, 1, n) {
            if (ind[u] > 0)
                sol.add(SS, u, ind[u]), totflow += ind[u];
            if (ind[u] < 0)
                sol.add(u, TT, -ind[u]);
        }
        sol.add(t, s, oo);
        int rflow = sol.MaxFlow(SS, TT);
        if (totflow > rflow) {
            cout << "please go home to sleep" << endl;
            return 0;
        }
        sol.es[m - 1].caps = sol.es[m - 2].caps = 0;
        cout << sol.MaxFlow(s, t) << endl;
    }
    最大流

     记住,删边的时候不是 $m$,是 $sol.m$

  • 相关阅读:
    列表第一篇文档与其他文档不同样式
    当前栏目判断有无子栏目
    当前栏目文章数
    有关当前焦点的标签,只有我能理解
    给推荐一个标识
    附件下载次数
    收藏代码
    关联会员头像信息
    当前三级折叠菜单导航
    centos7 安装配置apache
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/10521045.html
Copyright © 2020-2023  润新知