想看定义和证明可以到算法学习笔记(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;
}