Cod sursa(job #1241455)

Utilizator alexnekiNechifor Alexandru alexneki Data 13 octombrie 2014 16:17:24
Problema Flux maxim Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.3 kb
#include <iostream>
#include <fstream>

int const nMax = 1001;
int const capMax = 110010;

int n, m; //number of vertices and edges, respectively
int source, drain;
int cap[nMax][nMax], flux[nMax][nMax];
int vis[nMax]; //has the node been visited or not
int pred[nMax]; //for reconstructing the road
int maxUpdate[nMax]; //how much should the flux increase on one road

using namespace std;

struct node {
	int key;
	node *next;
};

node* x[nMax];

void bf() {
	int stack[nMax], nSt;

	for(int i=0; i<n; i++) {
		vis[i] = 0;
		pred[i] = -1;
		maxUpdate[i] = -1;
	}

	nSt = 1;
	stack[0] = source;
	vis[source] = 1;
	
	int k = 0;
	while(k < nSt) {
		//cout<<"Stack "<<stack[k]<<" "<<pred[stack[k]]<<endl;
		node* c = x[stack[k]];
		while(c) {
			int dif = cap[stack[k]][c->key] - flux[stack[k]][c->key];
			if(vis[c->key]==0 && dif > 0)  { //add in stack
				stack[nSt] = c->key;
				vis[c->key] = 1;
				pred[c->key] = stack[k];
				maxUpdate[c->key] = dif;
				if(stack[k]!=source && maxUpdate[c->key] > maxUpdate[stack[k]])
					maxUpdate[c->key] = maxUpdate[stack[k]];
				nSt++;
			}
			c = c->next;
		}
		k++;
	}
	
}

void updateFlux(int k, int value) { //how much should the flux increase on this road
	if(pred[k]>=0) {
		flux[pred[k]][k] += value;
		updateFlux(pred[k], value);
		//cout<<"("<<pred[k]<<","<<k<<","<<flux[pred[k]][k]<<")"<<endl;
	}
}

void printWay(int k) {
	if(pred[k]>=0) 
		printWay(pred[k]);
	cout<<k<<" ";
}

int main() {
	ifstream in("maxflow.in");
	streambuf* cinbuf = cin.rdbuf(); //save old buffer
	cin.rdbuf(in.rdbuf());


	ofstream out("maxflow.out");
	streambuf* coutbuf = cout.rdbuf(); //save old buffer
	cout.rdbuf(out.rdbuf());

	cin>>n>>m;
	int u, v, cost;
	for(int i=0; i<n; i++)
		x[i] = NULL;
	for(int i=0; i<n; i++)
		for(int j=0; j<n; j++)
			cap[i][j] = capMax;
	
	node* c;
	for(int i=0; i<m; i++) {
		cin>>u>>v>>cost;
		cap[u-1][v-1] = cost;
		c = new node;
		c->key = v-1;
		c->next = NULL;
		if(x[u-1])
			c->next = x[u-1];
		x[u-1] = c;
	}	
	source = 0;
	drain = n-1;
	
	while(1==1) {
		bf();
		if(maxUpdate[drain]<=0)
			break;
		//printWay(drain);
		//cout<<"-> "<<maxUpdate[drain]<<endl;
		updateFlux(drain, maxUpdate[drain]);
		//cout<<endl;
	}
	
	int totalFlux = 0;
	for(int i=0; i<n; i++)
		totalFlux += flux[source][i];
	cout<<totalFlux<<endl;
	
	cin.rdbuf(cinbuf);
	cout.rdbuf(coutbuf);
	return 0;
}