Cod sursa(job #1465389)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 27 iulie 2015 11:32:44
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.02 kb
#include <cstdio>
#include <cassert>
#include <algorithm>
#include <vector>
#include <list>
#include <queue>
#include <cstdlib>
#include <cstring>
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
 
class edge {
private:
	int toNod, flow, capacity, ID;
	edge* dup;
	edge(int n1, int n2, int cap, int nr) {
		toNod = n2;
		capacity = cap;
		flow = 0;
		ID = nr;
	}
	void assignDup(edge *E) {
		dup = E;
	}
	friend class graph;
};

class graph {
private:
	vector< list<edge> > adiac;
	int edgeCounter;
public:
	graph(int nrNod) {
		adiac.resize(nrNod);
		edgeCounter = 0;
	}
	void newEdge(int n1, int n2, int cap) {
		adiac[n1].push_back(edge(n1, n2, cap, edgeCounter));
		adiac[n2].push_back(edge(n2, n1, 0, edgeCounter));
		adiac[n1].back().assignDup(&adiac[n2].back());
		adiac[n2].back().assignDup(&adiac[n1].back());
		edgeCounter++;
	}
	int sendFlows(vector<int>& parent, vector<int>& capToParent, vector<int*>& flowToParent, vector<int*>& flowToParentDup, queue<int>& Q) {
		while (!Q.empty())
			Q.pop();
		int endNod = adiac.size() - 1;
		int s = 0;
		memset(&parent[0], 0xFF, parent.size() * sizeof(parent[0]));
		Q.push(0);
		parent[0] = -2;
		while (!Q.empty()) {
			int t = Q.front();
			Q.pop();
			for (auto i = adiac[t].begin(); i != adiac[t].end(); ++i) {
				if (parent[i->toNod] != -1 || i->capacity - i->flow == 0)
					continue;
				if (i->toNod == endNod) {
					int M = i->capacity - i->flow;
					int curNod = t;
					while (parent[curNod] != -2) {
						int availableFlow = capToParent[curNod] - *flowToParent[curNod];
						if (!availableFlow)
							break;
						if (availableFlow < M)
							M = availableFlow;
						curNod = parent[curNod];
					}
					if (parent[curNod] != -2)
						continue;

					i->flow += M;
					i->dup->flow -= M;
					curNod = t;
					while (parent[curNod] != -2) {
						*flowToParent[curNod] += M;
						*flowToParentDup[curNod] -= M;
						curNod = parent[curNod];
					}
					s += M;
				}
				else {
					int curNod = i->toNod;
					parent[curNod] = t;
					capToParent[curNod] = i->capacity;
					flowToParent[curNod] = &i->flow;
					flowToParentDup[curNod] = &i->dup->flow;
					Q.push(curNod);
				}
			}
		}
		return s;
	}
	int EdmondsKarp() {
		int s = 0;
		vector<int> parent(adiac.size());
		vector<int> capToParent(adiac.size());
		vector<int*> flowToParent(adiac.size());
		vector<int*> flowToParentDup(adiac.size());
		queue<int> Q;
		while (true) {
			int res = sendFlows(parent, capToParent, flowToParent, flowToParentDup, Q);
			if (!res)
				break;
			s += res;
		}
		return s;
	}
};

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