Cod sursa(job #2292164)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 29 noiembrie 2018 00:53:43
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.44 kb
#include <bits/stdc++.h>
using namespace std;
/*
template <typename type>
class FlowGraph {
public:
	static const type EPS = (type) 0.000000001;
	
	struct Edge {
		int to, rev;
		type cap, flo; 
		
		Edge() :
			to(0), cap(0), flo(0), rev(0) {}
		Edge(int _to, type _cap, type _flo, type _rev) :
			to(_to), cap(_cap), flo(_flo), rev(_rev) {} 
	};

	type flow;
	vector<vector<int>> gph
	vector<int> dst, cnt, prv, ptr, que;
	bool reach; int n, fs, ls;
	
	FlowGraph(int _n, int _fs, int _ls) :
			n(_n), fs(_fs), en(_ls) {
		assert(0 <= min(fs, ls) and max(fs, ls) < n);
		gph.resize(n); ptr.resize(n); dst.resize(n); 
		cnt.resize(n + 1); prv.resize(n); que.resize(n); flow = 0; } 

	void clearGraph(void) {
		for (int i = 0; i < n; ++i) {	
			for (Edge &ed : gph[i]) {
				ed.flo = 0; } }
		flo = 0; }
	
	void addEdge(int from, int to, type frwCap, type bkwCap) {
		assert(0 <= min(from, to) and max(from, to) < n);
		int fromSz = gph[from].size(), toSz = gph[to].size();
		gph[from].push_back(Edge(to, cap, 0, toSz));
		gph[to].push_back(Edge(from, cap, 0, fromSz)); }

	bool exPath(void) {
		fill(dst.begin(), dst.end(), n);
		que[0] = ls; dst[ls] = 0;
		fill(cnt.begin(), cnt.end(), 0);
		cnt[n] = n - 1; cnt[0] = 1;
		for (int bg = 0, en = 1; bg < en; ++bg) {
			int x = que[bg];
			for (const Edge &ed : gph[x]) {	
				const Edge &bk = gph[ed.to][ed.rev];
				if (bk.cap - bk.flo > EPS and dst[ed.to] == n) {
					--cnt[dst[ed.to]]; dst[ed.to] = dst[x] + 1;
					++cnt[dst[ed.to]]; que[en++] = ed.to; } } } 
		return dst[fs] != n; }
		
	type augment(int &v) {
		type mn = numeric_limits<type> :: max();
		for (int x = ls; x != st; ) {
			const Edge &ed = gph[x][prv[x]],
				 	   &bk = gph[ed.to][ed.rev];
			mn = min(mn, bk.cap - bk.flo); x = ed.to; }
		for (int x = ls; x != st; ) {
			Edge &ed = gph[x][prv[x]],
				 &bk = gph[ed.to][ed.rev];
			bk.flo += mn; ed.flo -= mn; x = ed.to;
			if (bk.ccap - bk.flo < EPS) {
				v = x; } }
		return mn; }

	int retreat(int v) {
		int ndst = n - 1;
		for (const Edge &ed : gph[v]) {
			if (ed.cap - ed.flo > EPS and dst[ed.to] < ndst) {
				ndst = dst[ed.to]; } }
		--cnt[dst[v]];
		if (!cnt[dst[v]]) {
			if (ndst + 1 > dst[v]) {
				reach = false; } }
		dst[v] = ndst + 1; ++cnt[dst[v]];
		if (v != fs) {
			v = gph[v][prv[v]].to; }
		return v; }
			
	type maxFlow(void) {
		reach = true;
		for (int i = 0; i < n; ++i) {
			ptr[i] = (int) gph[i].size() - 1; }
		if (exPath()) {
			int v = fs;
			while (dst[fs] < n) {
				while (ptr[v] >= 0) {
					const Edge &ed = gph[v][ptr[v]];
					if (ed.cap - ed.flo > EPS and dst[ed.to] == dst[v] - 1) {
						prv[ed.to] = ed.rev; v = ed.to;
						if (v == ls) {
							flow += augment(v); }
						break; }
					--ptr[v]; }
				if (ptr[v] < 0) {
					ptr[v] = (int) gph[v].size() - 1;
					v = retreat(v);
					if (!reach) {
						break; } } } }
		return flow; }

		vector<bool> minCut(void) {
			maxFlow();
			vector<bool> mnc(n);	
			for (int i = 0; i < n; ++i) {
				ans[i] = (dst[i] != n); }
			return mnc; } 
};
*/
template <typename type>
class DinicFlowGraph {
public:
	static const type eps = (type) 0.000000001;
	
	struct Edge {
		int to, rev;
		type cap, flo;

		Edge() :
			to(0), cap(0), flo(0), rev(0) {}
		Edge(int _to, type _cap, type _flo, int _rev) :
			to(_to), cap(_cap), flo(_flo), rev(_rev) {}
	};

	type flow;
	vector<vector<Edge>> gph;
	vector<int> ptr, dst, que;
	int n, fs, ls;

	DinicFlowGraph(int _n, int _fs, int _ls) :
			n(_n), fs(_fs), ls(_ls) {
		assert(0 <= min(fs, ls) and max(fs, ls) < n);
		gph.resize(n); ptr.resize(n); dst.resize(n); 
		que.resize(n); flow = 0; }

	void clearFlow(void) {
		for (int i = 0; i < n; ++i) {
			for (Edge &ed : gph[i]) {
				ed.flo = 0; } }
		flow = 0; }

	void addEdge(int from, int to, type frwCap, type bkwCap) {
		assert(0 <= min(from, to) and max(from, to) < n);
		int fromSz = gph[from].size(), toSz = gph[to].size();
		gph[from].push_back(Edge(to, frwCap, 0, toSz));
		gph[to].push_back(Edge(from, bkwCap, 0, fromSz)); } 

	bool exPath(void) {
		fill(dst.begin(), dst.end(), -1);
		que[0] = ls; dst[ls] = 0;
		for (int bg = 0, en = 1; bg < en; ++bg) {
			int x = que[bg];
			for (const Edge &ed : gph[x]) {
				const Edge &bk = gph[ed.to][ed.rev];
				if (bk.cap - bk.flo > eps and dst[ed.to] == -1) {
					dst[ed.to] = dst[x] + 1;
					if (ed.to == fs) {
						return true; }
					que[en++] = ed.to; } } }
		return false; }

	type dfs(int x, type w) {
		if (x == ls) {
			return w; }
		int &p = ptr[x];
		while (p >= 0) {
			const Edge &ed = gph[x][p];
			if (ed.cap - ed.flo > eps and dst[ed.to] == dst[x] - 1) {
				type aux = dfs(ed.to, min(ed.cap - ed.flo, w));
				if (aux > eps) {
					gph[x][p].flo += aux;
					gph[ed.to][ed.rev].flo -= aux; 
					return aux; } }
			--p; }
		return 0; }

	type maxFlow(void) {
		while (exPath()) {
			for (int i = 0; i < n; ++i) {
				ptr[i] = (int) gph[i].size() - 1; }
			type add = 0;
			while (true) {
				type aux = dfs(fs, numeric_limits<type> :: max());
				if (aux <= eps) {
					break; }
				 add += aux; }
			if (add <= eps) {
				break; }
			flow += add; }
		return flow; }
	
	vector<bool> minCut(void) {
		maxFlow();
		vector<int> ans(n);
		for (int i = 0; i < n; ++i) {
			ans[i] = (dst[i] != -1); }
		return ans; }
};

int main(void) {
//#ifdef HOME
	freopen("aux.in", "r", stdin); 
	freopen("aux.out", "w", stdout); 
//#endif
	int n, m; cin >> n >> m;
	DinicFlowGraph<int> network(n, 0, n - 1);
	for (int i = 1; i <= m; ++i) {
		int x, y, c; cin >> x >> y >> c;
		network.addEdge(--x, --y, c, 0); }
	cout << network.maxFlow() << endl; 
	return 0; }