Cod sursa(job #801127)

Utilizator Robert_MarksonTiberiu Popa Robert_Markson Data 23 octombrie 2012 16:21:56
Problema Flux maxim Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 3.39 kb
#include <algorithm>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstdlib>

//#define DEBUG
#define INFINITY 12345

using namespace std;

int BFS(const vector< vector<int> > neighbour_lists,
		int **capacity, int **flow, vector<int> &parent,
		int source, int sink)
{
	vector<int> path_capacity(neighbour_lists.size());
	queue<int> node_queue;
	unsigned long source_idx = (unsigned long) source;
	int residual_capacity;

	fill(parent.begin(), parent.end(), -1);
	parent[source_idx] = -2;

	path_capacity[source_idx] = INFINITY;
	node_queue.push(source);

	while (!node_queue.empty()) {
		int u = node_queue.front();
		unsigned long u_idx = (unsigned long) u;
		node_queue.pop();

		const vector<int> &n_list = neighbour_lists[u_idx];
		for (vector<int>::const_iterator it = n_list.begin(); it != n_list.end(); ++it) {
			int v = *it;
			unsigned long v_idx = (unsigned long) v;

			if (capacity[u_idx][v_idx] > flow[u_idx][v_idx] && parent[v_idx] == -1) {
				parent[v_idx] = u;
				residual_capacity = capacity[u_idx][v_idx] - flow[u_idx][v_idx];
				path_capacity[v_idx] = min(path_capacity[u_idx], residual_capacity);
				if(v == sink) {
					return path_capacity[v_idx];
				} else {
					node_queue.push(v);
				}
			}
		}
	}
	
	return 0;
}

void EdmondsKarp(const vector< vector<int> > neighbour_lists, int n,
			int **capacity,
			int source, int sink) {
	int **flow;
	size_t n_size = (size_t) n;
	vector<int> parent(n_size);
	int max_flow, saturate;
	int i, u, v;

	flow = new int*[n_size];
	for(i = 0; i < n; i++)
		flow[i] = (int*) calloc(n_size, sizeof(int));

	max_flow = 0;

	for (;;) {
		saturate = BFS(neighbour_lists, capacity, flow, parent, source, sink);
		if (saturate == 0)
			break;

		max_flow += saturate;
		v = sink;
		while (v != source) {
			u = parent[v];
			flow[u][v] += saturate;
			flow[v][u] -= saturate;
			v = u;
		}
	}

	FILE *f = fopen("maxflow.out", "wt");
	if (f != NULL) {
		fprintf(f, "%d\n", max_flow);
		fclose(f);
	}
}

int main() {
	FILE *f;
	int **capacity;
	int source, sink;
	int n, m;
	int u, v;

	f = fopen("maxflow.in", "rt");
	if (f == NULL) {
		fprintf(stderr, "Fiserul retea.in n-a putut fi deschis.\n");
		exit(-1);
	}

	if (fscanf(f, "%d", &n) != 1)
		exit(-1);
	if (fscanf(f, "%d", &m) != 1)
		exit(-1);

	capacity = new int*[n];
	for (int i = 0; i < n; i++) {
		capacity[i] = new int[n];
		fill(capacity[i], capacity[i] + n, 0);
	}

	vector< vector<int> > neighbour_lists(n);

	for (int i = 0; i < m; i++) {
		if (fscanf(f, "%d", &u) != 1)
			exit(-1);
		if (fscanf(f, "%d", &v) != 1)
			exit(-1);
		--u;
		--v;
		neighbour_lists[u].push_back(v);
		neighbour_lists[v].push_back(u);
		if (fscanf(f, "%d", &capacity[u][v]) == 0)
			exit(-1);
	}

	source = 0;
	sink = n - 1;

	#ifdef DEBUG

		fprintf(stderr, "debug: neighbour lists for all of the vertices\n");
		for (vector< vector<int> >::iterator v_it = neighbour_lists.begin();
				v_it != neighbour_lists.end(); ++v_it) {
			const vector<int> &n_list = *v_it;
			fprintf(stderr, "[");
			for (vector<int>::const_iterator it = n_list.begin(); it != n_list.end(); ++it)
				fprintf(stderr, " %d", *it);
			fprintf(stderr, " ]\n");
		}

		fprintf(stderr, "debug: capacity matrix\n");

		for (int i = 0; i < n; i++) {
			fprintf(stderr, "| ");
			for (int j = 0; j < n; j++)
				fprintf(stderr, "%d ", capacity[i][j]);
			fprintf(stderr, "|\n");
		}

	#endif

	EdmondsKarp(neighbour_lists, n, capacity, source, sink);

	// Ies de tot
	return 0;
}