Cod sursa(job #1976393)

Utilizator crushackPopescu Silviu crushack Data 3 mai 2017 11:46:50
Problema Flux maxim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.02 kb
#include <bits/stdc++.h>

#define INF 0x3f3f3f3f

using namespace std;


class MaxFlow {

	typedef vector<vector<int>> Graph;

	int flow_val_;
	Graph graph_;
	map<int, map<int, int>> capacity_;
	map<int, map<int, int>> flow_;

public:
	MaxFlow(int n) {
		graph_.resize(n + 1);
	}

	void add_edge(int x, int y, int c) {
		graph_[x].push_back(y);
		graph_[y].push_back(x);
		capacity_[x][y] = c;
		capacity_[y][x] = 0;
	}

	vector<int> bfs(int start) {
		vector<bool> visited(graph_.size(), false);
		vector<int> parent(graph_.size(), 0);

		queue<int> q;

		q.push(start);
		visited[start] = true;

		while (!q.empty()) {
			int node = q.front(); q.pop();

			for (int neigh : graph_[node]) {
				if (flow_[node][neigh] < capacity_[node][neigh] && !visited[neigh]) {
					parent[neigh] = node;
					visited[neigh] = true;
					q.push(neigh);
				}
			}
		}

		return parent;
	}

	int do_flow(int start, int finish) {
		int flow = 0;

		while (true) {

			auto parent = bfs(start);

			if (parent[finish] == 0) {
				break;
			}

			for (int neigh : graph_[finish]) {
				if (flow_[neigh][finish] == capacity_[neigh][finish] || parent[neigh] == 0) {
					continue;
				}

				int fmin = INF;

				for (int node = neigh; node != start; node = parent[node]) {
					fmin = min(fmin, capacity_[parent[node]][node] - flow_[parent[node]][node]);
				}

				if (fmin == 0) {
					continue;
				}

				for (int node = neigh; node != start; node = parent[node]) {
					flow_[parent[node]][node] += fmin;
					flow_[node][parent[node]] -= fmin;
				}

				flow += fmin;
			}
		}

		flow_val_ = flow;
		return flow;
	}

	map<int, map<int, int>> get_flow() {
		return flow_;
	}
};

int main() {

	freopen("maxflow.in", "r", stdin);
	freopen("maxflow.out", "w", stdout);

	int n, m;
	MaxFlow flow(n);

	cin >> n >> m;
	for (int i = 1; i <= m; ++ i) {
		int x, y, c;
		cin >> x >> y >> c;

		flow.add_edge(x, y, c);
	}

	cout << flow.do_flow(1, n) << endl;

	return 0;
}