0
点赞
收藏
分享

微信扫一扫

网络流

求索大伟 2022-02-25 阅读 62
网络

想看定义和证明可以到算法学习笔记(28): 网络流 - 知乎 

最大流

EK算法

// 例题https://www.acwing.com/problem/content/description/2173/
// EK算法时间复杂度为O(点数*边数^2),但是这个复杂度非常玄学,上界非常宽松
// 基本可以解决点数+边数<10000的问题
#include <bits/stdc++.h>
using namespace std;

const int N = 10010;
const int M = 20010;

map<pair<int, int>, int> graphW;
unordered_set<int> g[N];

int n, m;
int S, T;

int ans = 0;
int d[N];
int pre[N];
int st[N];

void addEdge(int from, int to, int flow) {
    pair<int, int> p1 = make_pair(from, to);
    graphW[p1] += flow;
    pair<int, int> p2 = make_pair(to, from);
    graphW[p2] += 0;
    g[from].insert(to);
    g[to].insert(from);
}

bool bfs() {
    memset(st, 0, sizeof(st));
    queue<int> q;
    q.push(S);
    st[S] = 1;
    d[S] = 100000010;
    while (q.size()) {
        int t = q.front();
        q.pop();
        for (auto ver : g[t]) {
            pair<int, int> edge = make_pair(t, ver);
            int f = graphW[edge];
            if (!st[ver] && f) {
                st[ver] = 1;
                d[ver] = min(d[t], f);
                pre[ver] = t;
                if (ver == T)
                    return true;
                q.push(ver);
            }
        }
    }
    return false;
}

int main() {
    cin >> n >> m >> S >> T;
    for (int i = 0; i < m; i++) {
        int a, b, w;
        cin >> a >> b >> w;
        addEdge(a, b, w);
    }
    while (bfs()) {
        ans += d[T];
        int from = T;
        int to = pre[from];
        while (1) {
            pair<int, int> E = make_pair(from, to);
            pair<int, int> revE = make_pair(to, from);
            graphW[E] += d[T];
            graphW[revE] -= d[T];
            if (to == S)
                break;
            from = to;
            to = pre[from];
        }
    }
    cout << ans << endl;
    return 0;
}

 

举报

相关推荐

0 条评论