Pagini recente » Cod sursa (job #915558) | Cod sursa (job #2631308) | Cod sursa (job #558233) | Cod sursa (job #2514256) | Cod sursa (job #3262763)
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#include <queue>
#define debug(x) #x << " = " << x << '\n';
using ll = long long;
#define int ll
const int INF = 1e18;
struct Dinic {
struct Edge {
int to, flow, cap;
};
int n;
std::vector<Edge> e;
std::vector<std::vector<int>> g;
std::vector<int> dist;
int source, sink;
Dinic() {}
Dinic(int _n) {
n = _n;
g.resize(n + 1);
dist.resize(n + 1);
}
void add_edge(int u, int v, int cap) {
e.push_back({v, 0, cap});
e.push_back({u, 0, 0});
assert(1 <= u && u <= n);
assert(1 <= v && v <= n);
g[u].push_back((int) e.size() - 2);
g[v].push_back((int) e.size() - 1);
}
bool can_bfs() {
std::queue<int> q;
dist.assign(n + 1, INF);
q.push(source);
dist[source] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
for (const auto &ind : g[u]) {
auto &[v, flow, cap] = e[ind];
if (flow < cap && dist[u] + 1 < dist[v]) {
dist[v] = 1 + dist[u];
q.push(v);
}
}
}
return dist[sink] != INF;
}
int do_push(int u, int F) {
if (u == sink) {
return F;
}
int pushed = 0;
for (const auto &ind : g[u]) {
auto &[v, flow, cap] = e[ind];
if (dist[u] + 1 == dist[v] && flow < cap) {
int push = do_push(v, std::min(F, cap - flow));
pushed += push;
flow += push;
F -= push;
}
}
return pushed;
}
int max_flow(int _source, int _sink) {
source = _source;
sink = _sink;
int answer = 0;
while (can_bfs()) {
int push = do_push(source, INF);
answer += push;
if (push == 0) {
break;
}
}
return answer;
}
};
signed main() {
#ifdef LOCAL
freopen("input.txt", "r", stdin);
#else
freopen("maxflow.in", "r", stdin);
freopen("maxflow.out", "w", stdout);
#endif
std::ios_base::sync_with_stdio(false);
std::cin.tie(0);
int n, m;
std::cin >> n >> m;
Dinic F(n + 1);
for (int i = 0; i < m; i++) {
int u, v, c;
std::cin >> u >> v >> c;
F.add_edge(u, v, c);
}
std::cout << F.max_flow(1, n);
return 0;
}