Cod sursa(job #3261491)

Utilizator amcbnCiobanu Andrei Mihai amcbn Data 6 decembrie 2024 13:31:25
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.27 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");

// daca o muchie are capacitatea C si fluxul care trece prin ea e F,
// putem sa consideram ca de fapt are capacitatea C' = C - F
struct edge {
	int from, to;
	int capacity;
	int flow;
	edge(int from, int to, int capacity, int flow)
		: from(from), to(to), capacity(capacity), flow(flow) {

	}
};

// Edmonds-Karp algorithm for maximum flow
// Time complexity: O(V * E^2)
struct EdmondsKarp {
	int V = 0, E = 0;
	int source = 0, sink = 0;
	vector<vector<int>> g;
	vector<edge> edges;
	EdmondsKarp() {}
	EdmondsKarp(int V, int source, int sink) : V(V), source(source), sink(sink) {
		g.resize(V + 1);
	}
	void addEdge(int u, int v, int c) {
		g[u].push_back(E++);
		edges.emplace_back(u, v, c, 0);
		g[v].push_back(E++);
		edges.emplace_back(v, u, 0, 0);
	}
	int sendFlow(vector<int>& parent) {
		parent.assign(V + 1, -1);
		parent[source] = source;
		queue<pair<int, int>> q;
		q.push({ source, 1e9 });
		while (q.size()) {
			int u = q.front().first;
			int flow = q.front().second;
			for (auto& i : g[u]) {
				auto& e = edges[i];
				// trimit flux prin muchia curenta daca mai e loc
				if (parent[e.to] == -1 && e.capacity > e.flow) {
					parent[e.to] = u;
					int new_flow = min(flow, e.capacity - e.flow);
					if (e.to == sink) {
						return new_flow;
					}
					q.push({ e.to, new_flow });
				}
			}
			q.pop();
		}
		return 0;
	}
	int maxFlow() {
		int flow = 0, new_flow;
		vector<int> parent(V + 1);
		while (new_flow = sendFlow(parent)) {
			flow += new_flow;
			vector<int> path{ sink };
			while (path.back() != source) {
				path.push_back(parent[path.back()]);
			}
			reverse(path.begin(), path.end());
			int u = sink;
			while (u != source) {
				int v = parent[u];
				for (auto& i : g[v]) {
					auto& e = edges[i];
					if (e.to == u) {
						e.flow += new_flow;
						edges[i ^ 1].flow -= new_flow;
						break;
					}
				}
				u = v;
			}
		}
		return flow;
	}
};

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n, m;
	fin >> n >> m;
	EdmondsKarp foo(n, 1, n);
	for (int i = 1; i <= m; ++i) {
		int u, v, c;
		fin >> u >> v >> c;
		foo.addEdge(u, v, c);
	}
	fout << foo.maxFlow();
}