Cod sursa(job #499221)

Utilizator vlad_DVlad Dumitriu vlad_D Data 9 noiembrie 2010 03:42:43
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

#define noduri 351
#define INF 99999999
#define pb(a) push_back(a)
vector<vector<int> > G; // grafu propriu-zis
int CAP[noduri][noduri]; // capacitati
int P[noduri][noduri]; // preturi
int N;
void max_flow_cost(int &flow, int &cost, int sursa, int sink) {
	flow = 0; cost = 0;
	while (1) {
		int BFS[noduri];
		int D[noduri], U[noduri];
		for (int i = 0; i <= N; ++i) {
			BFS[i] = U[i] = 0;
			D[i] = INF;
		}

		D[sursa] = 0; U[sursa] = 1;
		queue<int> Q;
		Q.push(sursa);
		while (!Q.empty()) {
			int nod = Q.front(); Q.pop();
			for (int i = 0; i < G[nod].size(); ++i) {
				int nod2 = G[nod][i];
				if (CAP[nod][nod2] <= 0 || D[nod2] <= D[nod] + P[nod][nod2])
					continue;
				D[nod2] = D[nod] + P[nod][nod2];
				BFS[nod2] = nod;
				if (!U[nod2]) {Q.push(nod2); U[nod2] = 1;}
			}
			U[nod] = 0;
		}
		if (D[sink] == INF) return;
		int cresc = INF;
		for (int i = sink; i != sursa; i = BFS[i]) 
			cresc = min(cresc, CAP[BFS[i]][i]);
		flow += cresc;
		cost += cresc * D[sink];
		for (int i = sink; i != sursa; i = BFS[i]) {
			CAP[BFS[i]][i] -= cresc;
			CAP[i][BFS[i]] += cresc;
		}
	}
}
int main() {
	freopen("fmcm.in", "r", stdin);
	freopen("fmcm.out", "w", stdout);
	int sink, sursa, M;	
	scanf("%d %d %d %d", &N, &M, &sursa, &sink);
	G.resize(N+4);
	while (M--) {
		int a, b, c, d;
		scanf("%d %d %d %d", &a, &b, &c, &d);
		G[a].pb(b); G[b].pb(a);
		CAP[a][b] = c; CAP[b][a] = 0;
		P[a][b] = d; P[b][a] = -d;
	}
	int flow, cost;

	max_flow_cost(flow, cost, sursa, sink);
	printf("%d\n", cost);
	return 0;
}