Cod sursa(job #1462050)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 16 iulie 2015 23:47:39
Problema Flux maxim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.08 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, 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* f = new int(0);
		adiac[n1].push_back(edge(n2, cap, f));
		adiac[n2].push_back(edge(-n1, cap, f));
	}
	int size() { return adiac.size() - 1; }
	int sendFlows(int nod, int endNod, vector<int> &parent, vector<int*> &flowArcToParent, vector<int> &capArcToParent, vector<char> &isForwardArc, queue<int>& Q) {
		int s = 0;
		memset(&parent[0], 0xFF, parent.size()*sizeof(parent[0]));
		while (!Q.empty())
			Q.pop();
		Q.push(nod);
		parent[nod] = 0;
		while (!Q.empty()) {
			int t = Q.front();
			Q.pop();
			for (auto i = adiac[t].begin(); i != adiac[t].end(); ++i) {
				int curnod = i->toNod > 0 ? i->toNod : -(i->toNod);
				if (curnod == endNod) {
					int MF = i->capacity - *i->flow;
					int aux = t;
					while (parent[aux]) {
						int availableFlow = isForwardArc[aux] ? capArcToParent[aux] - *flowArcToParent[aux] : *flowArcToParent[aux];
						if (!availableFlow)
							break;
						if (availableFlow < MF)
							MF = availableFlow;
						aux = parent[aux];
					}
					if (!parent[aux]) {
						if (i->toNod > 0)
							*i->flow += MF;
						else
							*i->flow -= MF;
						aux = t;
						while (parent[aux]) {
							if (isForwardArc[aux])
								*flowArcToParent[aux] += MF;
							else
								*flowArcToParent[aux] -= MF;
							aux = parent[aux];
						}
					}
					s += MF;
				}
				else if (parent[curnod] == -1) {
					int availableFlow = i->toNod > 0 ? i->capacity - *i->flow : *i->flow;
					if (availableFlow) {
						Q.push(curnod);
						parent[curnod] = t;
						flowArcToParent[curnod] = i->flow;
						capArcToParent[curnod] = i->capacity;
						if (i->toNod > 0)
							isForwardArc[curnod] = 1;
						else
							isForwardArc[curnod] = 0;
					}
				}
			}
		}
		return s;
	}
	int EdmondsKarp(int source, int sink) {
		int s = 0;
		vector<int> parent(size() + 1), caps(size() + 1);
		vector<int*> flows(size() + 1);
		vector<char> isForward(size() + 1);
		queue<int> Q;
		while (true) {
			int flowSent = sendFlows(source, sink, parent, flows, caps, isForward, Q);
			if (!flowSent)
				break;
			s += flowSent;
			//fprintf(stderr, "%d\n", s);
		}
		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->EdmondsKarp(1, N));
	return 0;
}