Cod sursa(job #617548)

Utilizator root/boot/vmlinuz root Data 15 octombrie 2011 00:12:10
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
/* Versiunea cu smen */

#include <stdio.h>
#include <vector>
#include <string.h>

using namespace std;

#define MN (1000)

int C[MN][MN]; // capacity
int F[MN][MN]; // flow
int P[MN]; // parent
vector<int> G[MN]; // graph (adjacency list)
int seen[MN]; // visited
int N, M;

int bfs()
{
	// Source is 0, Sink is N-1
	int queue[MN+1] = {1, 0}, q;
	int i;

	memset(seen, 0, sizeof(seen));
	seen[0] = 1;

	for(q = 1; q <= queue[0]; ++q) {
		int a = queue[q]; // current node
		int b; // neighbour
		//printf("Treating %d\n", a);
		if(a == N-1)
			continue;
		for(i = 0; i < G[a].size(); ++i) {
			b = G[a][i];
			if(seen[b] || F[a][b] >= C[a][b])
				continue;
			//printf("Added %d\n to the queue.\n", b);
			seen[b] = 1;
			queue[++queue[0]] = b;
			P[b] = a;
		}
	}

	return seen[N-1]; // did we reach the source?
}

int main()
{
	freopen("maxflow.in", "r", stdin);
	freopen("maxflow.out", "w", stdout);
	
	int i, j;
	int flow; // total flow
	int faug; // maximum flow allowed on the augmenting path

	scanf("%d %d", &N, &M);
	for(i = 0; i < M; ++i) {
		int a, b, c;
		scanf("%d %d %d", &a, &b, &c);
		--a; --b;
		G[a].push_back(b);
		G[b].push_back(a); // construct the residual graph
		C[a][b] = c;
		// Of course, C[b][a] = 0
	}

	for(flow = 0; bfs(); ) {
		for(i = 0; i < G[N-1].size(); ++i) {
			int node = G[N-1][i];
			if(!seen[node] || F[node][N-1] >= C[node][N-1])
				continue;
			memset(&faug, 0x3f, sizeof(faug));
			P[N-1] = node;
			for(j = N-1; j; j = P[j])
				faug = min(faug, C[P[j]][j]-F[P[j]][j]);
			for(j = N-1; j; j = P[j]) {
				F[P[j]][j] += faug;
				F[j][P[j]] -= faug;
			}
			//printf("faug %d\n", faug);
			flow += faug;
		}
	}

	printf("%d\n", flow);

	return 0;
}