• [洛谷 P3376] 网络最大流 | 模板 (ISAP 算法) 入门


    题目链接

    题目描述

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

    输入格式

    第一行包含四个正整数 n n n, m m m, s s s, t t t,分别表示点的个数、有向边的个数、源点序号、汇点序号。

    接下来M行每行包含三个正整数 ui ,vi,wi ,表示第 i 条有向边从 ui 出发,到达 vi,边权为 wi即该边最大流量为 wi)。
    输出格式

    一行,包含一个正整数,即为该网络的最大流。
    输入输出样例

    4 5 4 3
    4 2 30
    4 3 20
    2 3 20
    2 1 30
    1 3 40
    
    50
    

    样例输入输出 1 解释

    在这里插入图片描述在这里插入图片描述

    struct Edge {
        int u, v;
        ll cap, flow;
        Edge(int _u, int _v, ll _cap, ll _flow) {
            u = _u, v = _v, cap = _cap, flow = _flow;
        }
    };
    struct ISAP {
        vector<Edge> edge;
        vector<int> G[maxn];
        ll dis[maxn], cur[maxn];
        int n, s, t;
        ll p[maxn], num[maxn];
        bool vis[maxn];
        void init(int _n, int _s, int _t) {
            this->n = _n, this->s = _s, this->t = _t;
            for (int i = 1; i <= _n; i++) G[i].clear();
            edge.clear();
        }
        void add(int u, int v, ll cap) {
            edge.push_back(Edge(u, v, cap, 0));
            edge.push_back(Edge(v, u, 0, 0));
            int siz = edge.size();
            G[u].push_back(siz - 2);
            G[v].push_back(siz - 1);
        }
        void BFS() {
            for (int i = 1; i <= n; i++) dis[i] = n;
            queue<int> que;
            que.push(t);
            dis[t] = 0;
            while (que.size()) {
                int u = que.front();
                que.pop();
                for (int i = 0; i < G[u].size(); i++) {
                    Edge &e = edge[G[u][i]];
                    if (e.cap <= e.flow && dis[e.v] == n) {
                        que.push(e.v);
                        dis[e.v] = dis[u] + 1;
                    }
                }
            }
        }
        ll Augment() {
            ll x = t, a = 0x3f3f3f3f;
            while (x != s) {
                Edge &e = edge[p[x]];
                a       = min(a, e.cap - e.flow);
                x       = edge[p[x]].u;
            }
            x = t;
            while (x != s) {
                edge[p[x]].flow += a;
                edge[p[x] ^ 1].flow -= a;
                x = edge[p[x]].u;
            }
            return a;
        }
        ll MaxFlow() {
            ll flow = 0LL;
            ///bfs();//wa
            BFS();//ac
            memset(num, 0, sizeof num);
            for (int i = 0; i <= n; i++) num[dis[i]]++;
            int x = s;
            memset(cur, 0, sizeof cur);
            while (dis[s] < n) {
                if (x == t) {
                    flow += Augment();
                    x = s;
                }
                int ok = 0;
                for (int i = cur[x]; i < G[x].size(); i++) {
                    Edge &e = edge[G[x][i]];
                    if (e.cap > e.flow && dis[x] == dis[e.v] + 1) {
                        ok     = 1;
                        p[e.v] = G[x][i];
                        cur[x] = i;
                        x      = e.v;
                        break;
                    }
                }
                if (!ok) {
                    ll m = n - 1;
                    for (int i = 0; i < G[x].size(); i++) {
                        Edge &e = edge[G[x][i]];
                        if (e.cap > e.flow) m = min(m, dis[e.v]);
                    }
                    if (--num[dis[x]] == 0) break;
                    num[dis[x] = m + 1]++;
                    cur[x] = 0;
                    if (x != s) x = edge[p[x]].u;
                }
            }
            return flow;
        }
    } solve;
    int main() {
        int n = read, m = read, s = read, t = read;
        solve.init(n, s, t);
        for (int i = 1; i <= m; i++) {
            int u = read, v = read;
            ll cap = read;
            solve.add(u, v, cap);
        }
        cout << solve.MaxFlow() << endl;
        return 0;
    }
    
  • 相关阅读:
    POJ 2593&&2479:Max Sequence
    POJ 2115:C Looooops
    杭电2187--悼念512汶川大地震遇难同胞——老人是真饿了
    南阳448--寻找最大数
    杭电2544--最短路(Floyd)邻接表使用方法模板
    杭电2141--Can you find it?
    杭电1242--Rescue(BFS+优先队列)
    杭电1241--Oil Deposits(Dfs)
    南阳42--一笔画问题
    杭电1950--Bridging signals (二分法→ →LIS)
  • 原文地址:https://www.cnblogs.com/PushyTao/p/15459799.html
Copyright © 2020-2023  润新知