Cod sursa(job #1462664)

Utilizator GilgodRobert B Gilgod Data 18 iulie 2015 17:52:30
Problema Flux maxim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.03 kb
#include <iostream>
#include <fstream>
#include <assert.h>
#include <list>
#include <queue>
#include <bitset>
#include <cstring>

#define min(a,b) ((a)<(b))?(a):(b)
#define forever while(1)
#define pop() Q.front(); Q.pop()

const int NMAX = 1000;
const int MMAX = 5000;

const char IN[] = "maxflow.in", OUT[] = "maxflow.out";

using namespace std;

int N, M;
int G[NMAX][NMAX];
int Gf[NMAX][NMAX];

const int INF = 0x3f3f3f3f;
const int source = 1;
int drain;

inline void read_data()
{
	assert(freopen(IN, "r", stdin));
	assert(scanf("%d %d", &N, &M));
	drain = N;
	for (int i = 0; i < M; ++i) {
		int u, v, c;
		assert(scanf("%d %d %d", &u, &v, &c));
		G[u][v] = c;
		Gf[u][v] = c; 
	}
	fclose(stdin);
}

int PI[NMAX];
bitset<NMAX> inQ; 
list<int> path;

bool find_augmenting_paths()
{
	queue<int> Q;
	inQ.reset();
	memset(PI, 0, sizeof(PI));
	Q.push(source);
	inQ[source].flip();
	while (!Q.empty()) {
		int u = pop();
		for (int v = 1; v <= N; ++v) {
			if (Gf[u][v] && !inQ[v]) {
				PI[v] = u;
				Q.push(v);
				inQ[v].flip();
			}
		}
	}
	return inQ[N];
}


int saturate_path()
{
	int maximum_path_flow = path.front(); path.pop_front();
	std::list<int>::iterator it = path.begin();
	for (int i = 0; i < path.size() - 1; ++i) {
		int u = *it;
		int v = *(++it);
		Gf[u][v] -= maximum_path_flow;
		Gf[v][u] += maximum_path_flow;
	}
	return maximum_path_flow;
}

int maxflow()
{
	int mflow = 0;
	forever {
		if(!find_augmenting_paths()) break;
		for (int u = 1; u < N; ++u) {
			if (inQ[u] && Gf[u][N]) {
				path.clear();
				path.push_back(N);
				int path_flow = Gf[u][N];
				for (int node = u; node != source; node = PI[node]) {
					path.push_front(node);
					path_flow = min(path_flow, Gf[PI[node]][node]);
				}
				path.push_front(source);
				path.push_front(path_flow);
				if (path_flow == 0) continue;
				mflow += saturate_path();
			}
		}
	}
	return mflow;
}

int main()
{
	read_data();
	fprintf(fopen(OUT, "w"), "%d\n", maxflow());
	return 0;
}