Cod sursa(job #796031)

Utilizator ciprianfFarcasanu Alexandru Ciprian ciprianf Data 10 octombrie 2012 13:24:21
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include <stdio.h>
#include <vector>
#include <queue>
using namespace std;
#define N_MAX 355
#define INF 2000000000
vector<int> G[N_MAX], F[N_MAX], C[N_MAX], Cost[N_MAX];
queue<int> q;
bool in[N_MAX];
int Dist[N_MAX], T[N_MAX], T2[N_MAX], T3[N_MAX];
int n, m;
int source, dest;

void add_muchie(int x, int y, int cap, int cost) {
	G[x].push_back(y);
	C[x].push_back(cap);
	Cost[x].push_back(cost);
	F[x].push_back(0);
	
	G[y].push_back(x);
	C[y].push_back(0);
	Cost[y].push_back(-cost);
	F[y].push_back(0);
}

void vecini(int x) {
	for(unsigned int i = 0; i < G[x].size(); i++) {
		if(G[x][i] == T[x]) {
			T3[x] = i;
		}
		
		if(C[x][i] == F[x][i] || Dist[G[x][i]] <= Dist[x] + Cost[x][i]) {
			continue;
		}
		Dist[G[x][i]] = Dist[x] + Cost[x][i];
		if(!in[G[x][i]]) {
			q.push(G[x][i]);
		}
		in[G[x][i]] = true;
		T[G[x][i]] = x;
		T2[G[x][i]] = i;
	}
}

int BellmanFord() {
	
	for(int i = 1; i <= n; i++) {
		Dist[i] = INF;
	}
	
	Dist[source] = 0;
	q.push(source);
	while(!q.empty()) {
		int x = q.front();
		q.pop();
		in[x] = false;
		//printf("%d %d\n", x, Dist[x]);
		if(x == dest) {
			continue;
		}
		vecini(x);
	}
	
	if(Dist[dest] == INF) {
		return 0;
	}

	int flow = INF;
	for(int i = dest; i != source; i = T[i]) {
		int t = T[i];
		flow = min(flow, C[t][T2[i]] - F[t][T2[i]]);
	}
	
	for(int i = dest; i != source; i = T[i]) {
		int t = T[i];
		F[t][T2[i]] += flow;
		F[i][T3[i]] -= flow;
	}
	
	return flow*Dist[dest];
}
	
	
int main() {
	freopen("fmcm.in", "r", stdin);
	freopen("fmcm.out", "w", stdout);
	
	scanf("%d%d%d%d", &n, &m, &source, &dest);
	
	for(int i = 0; i < m; i++) {
		int x, y, cap, cost;
		scanf("%d%d%d%d", &x, &y, &cap, &cost);
		add_muchie(x,y,cap,cost);
	}
	int sol = 0;
	while(1) {
		sol += BellmanFord();
		if(Dist[dest] == INF) {
			break;
		}
	}
	
	printf("%d\n", sol);
	return 0;
}