Cod sursa(job #1461583)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 15 iulie 2015 23:52:41
Problema Flux maxim Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.61 kb
#include <cstdio>
#include <cassert>
#include <algorithm>
#include <vector>
#include <list>
using namespace std;
#define _submit
#ifdef _submit
#define InFile "maxflow.in"
#define OtFile "maxflow.out"
#else
#define InFile "fis.in"
#define OtFile "fis.out"
#endif

#define INFINIT 120000
#define MAXEDGES 5100

class edge {
private:
	int toNod, *capacity, *flow;
	edge(int N, int* p, int* f) {
		toNod = N;
		capacity = p;
		flow = f;
	}
	friend class graph;
};

class graph {
private:
	vector< list<edge> > adiac;
public:
	graph(int N) { adiac.resize(N + 1); }
	void addEdge(int n1, int n2, int cap) {
		int* p = new int(cap);
		int* f = new int(0);
		adiac[n1].push_back(edge(n2, p, f));
		adiac[n2].push_back(edge(-n1, p, f));
	}
	int size() { return adiac.size() - 1; }
	bool getAugmentingPath(int nod, int endNod, vector<char>& visited, vector<int*>& pathFlows, int& minFlow) {
		visited[nod] = 1;
		if (nod == endNod)
			return true;
		for (auto i = adiac[nod].begin(); i != adiac[nod].end(); ++i) {
			int neigh = i->toNod > 0 ? i->toNod : -i->toNod;
			if (visited[neigh])
				continue;
			bool isForwardArc = i->toNod > 0 ? true : false;
			bool isAvailable = false;
			if (isForwardArc && *(i->flow) < *(i->capacity)) {
				isAvailable = true;
				if (*(i->capacity) - *(i->flow) < minFlow)
					minFlow = *(i->capacity) - *(i->flow);
			}
			else if (!isForwardArc && *(i->flow) > 0) {
				isAvailable = true;
				if (*(i->flow) < minFlow)
					minFlow = *(i->flow);
				*(i->flow) = -(*(i->flow));
			}
			if (isAvailable) {
				if (getAugmentingPath(neigh, endNod, visited, pathFlows, minFlow)) {
					pathFlows.push_back(i->flow);
					return true;
				}
			}
		}
		return false;
	}
	int FordFulkerson(int source, int sink) {
		int s = 0;
		vector<int*> pathFlows;
		pathFlows.reserve(MAXEDGES);
		vector<char> visited(size() + 1);
		while (true) {
			int minFlow = INFINIT;
			visited.assign(size() + 1, 0);
			pathFlows.clear();
			getAugmentingPath(source, sink, visited, pathFlows, minFlow);
			if (!pathFlows.size())
				break;
			s += minFlow;
			for (auto i = pathFlows.begin(); i != pathFlows.end(); ++i) {
				if (**i < 0) {
					**i = -(**i);
					**i -= minFlow;
				}
				else
					**i += minFlow;
			}
		}
		return s;
	}
};

int main() {
	assert(freopen(InFile, "r", stdin));
	assert(freopen(OtFile, "w", stdout));
	int N, M;
	scanf("%d%d", &N, &M);
	graph* G = new graph(N);
	for (int i = 0; i < M; i++) {
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		G->addEdge(a, b, c);
	}
	printf("%d\n", G->FordFulkerson(1, N));
	return 0;
}