Pagini recente » Cod sursa (job #1797565) | Cod sursa (job #2160706) | Cod sursa (job #67415) | Cod sursa (job #827061) | Cod sursa (job #1991907)
#include <bits/stdc++.h>
using namespace std;
struct Dinic {
struct Edge {
int to, cap, flow, nxt;
};
vector<Edge> edges;
vector<int> graph, at, dist;
int src = 0, dest = 1;
Dinic(int n, int m = 0) : graph(n, -1), dist(n, -1) {
edges.reserve(2*m);
}
void m_add_edge(int from, int to, int cap) {
edges.push_back(Edge {to, cap, 0, graph[from]});
graph[from] = edges.size() - 1;
}
void add_edge(int from, int to, int cap) {
m_add_edge(from, to, cap);
m_add_edge(to, from, 0);
}
void set_source_sink(int src, int dest) {
this->src = src; this->dest = dest;
}
bool bfs(int step) {
queue<int> q;
fill(dist.begin(), dist.end(), -1);
dist[src] = 0;
q.push(src);
while (!q.empty()) {
int node = q.front(); q.pop();
for (int i = graph[node]; i >= 0; i = edges[i].nxt) {
const auto &e = edges[i];
if (dist[e.to] == -1 && e.flow + step <= e.cap) {
dist[e.to] = dist[node] + 1;
q.push(e.to);
}
}
}
return dist[dest] != -1;
}
int dfs(int node, int flow) {
if (flow == 0) return 0;
if (node == dest) return flow;
while (at[node] != -1) {
int eid = at[node];
const auto &e = edges[eid];
if (dist[e.to] == dist[node] + 1) {
if (int ret = dfs(e.to, min(flow, e.cap - e.flow))) {
edges[eid].flow += ret;
edges[eid^1].flow -= ret;
return ret;
}
}
at[node] = e.nxt;
}
return 0;
}
int compute() {
int ret = 0, step = (1 << 30);
while (step > 0) {
if (!bfs(step)) step /= 2;
else {
at = graph;
while (int flow = dfs(src, step))
ret += flow;
}
}
return ret;
}
};
int main() {
freopen("maxflow.in", "r", stdin);
freopen("maxflow.out", "w", stdout);
int n, m; cin >> n >> m;
Dinic D(n, m);
while (m--) {
int a, b, c; cin >> a >> b >> c;
D.add_edge(a - 1, b - 1, c);
}
D.set_source_sink(0, n - 1);
cout << D.compute() << endl;
return 0;
}