Cod sursa(job #2293309)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 30 noiembrie 2018 19:54:00
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <bits/stdc++.h>
using namespace std;

template <typename type>
class Dinic {

private:

	static const type eps = (type) 0.000000001;

	struct Edge {
		int to, next;
		type cap, flo;
		
		Edge() : 
			to(0), next(0), cap(0), flo(0) {}
		Edge(int _to, int _next, type _cap, type _flo) :
			to(_to), next(_next), cap(_cap), flo(_flo) {}
	};

	int sz, st, fi;
	vector<Edge> edg;
	vector<int> aux, pos, adj, dst, que;

public:

	Dinic(int _sz) : sz(_sz) {
		que = dst = aux = pos = vector<int>(sz, -1); }

	void addEdge(int from, int to, type cap, type rvcap = 0) {
		edg.push_back(Edge(to, aux[from], cap, 0));
		aux[from] = edg.size() - 1;
		edg.push_back(Edge(from, aux[to], rvcap, 0));
		aux[to] = edg.size() - 1; }

	bool bfs(void) {
		fill(begin(dst), end(dst), 0); dst[st] = 1; que[0] = st;
		for (int bg = 0, en = 1; bg < en; ++bg) {
			int x = que[bg];
			for (int p = aux[x]; p != -1; p = edg[p].next) {
				const Edge &ed = edg[p];
				if (!dst[ed.to] and ed.cap - ed.flo > eps) {
					dst[ed.to] = dst[x] + 1; que[en++] = ed.to; } } } 
		return dst[fi]; }

	type dfs(int x, type fl = numeric_limits<type> :: max()) {
		if (x == fi) {
			return fl; }
		type agm;
		for (; adj[x] != -1; adj[x] = edg[adj[x]].next) {
			const Edge &ed = edg[adj[x]];
			if (dst[x] + 1 == dst[ed.to] and ed.cap - ed.flo > eps) {
				agm = dfs(ed.to, min(ed.cap - ed.flo, fl));
				if (agm > eps) {
					edg[adj[x]].flo += agm;
					edg[adj[x] ^ 1].flo -= agm;
					return agm; } } } 
		return 0; }

	type maxFlow(int _st, int _fi) {
		st = _st; fi = _fi; type flo = 0, add;
		while (bfs()) {
			adj = aux;
			while ((add = dfs(st)) > eps) {
				flo += add; } }
		return flo; }

	vector<bool> minCut(int _st, int _fi) {
		maxFlow(_st, _fi);
		vector<bool> ans(sz);
		for (int i = 0; i < sz; ++i) {
			ans[i] = (dst[i] != 0); }
		return ans; }
};

int main(void) {
	freopen("maxflow.in", "r", stdin);
	freopen("maxflow.out", "w", stdout);
	int n, m; cin >> n >> m;
	Dinic<int> network(n + 1);
	for (int i = 1; i <= m; ++i) {
		int x, y, c; cin >> x >> y >> c;
		network.addEdge(x, y, c); }
	cout << network.maxFlow(1, n); 
	return 0; }