Cod sursa(job #328908)

Utilizator CezarMocanCezar Mocan CezarMocan Data 3 iulie 2009 19:20:07
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
#include <cstdio>
#include <vector>
#include <cstring>
#define inf 2000000000
#define maxn 352

using namespace std;

int n, m, s, d, i, j, aa, bb, cc, zz;
vector <int> v[maxn], z[maxn]; 
int c[maxn][maxn], f[maxn][maxn];
int cst[maxn], flux[maxn], up[maxn], viz[maxn];
int ok, fmax, rez;

void init() {
	int i;
	memset(up, -1, sizeof(up));
	memset(viz, 0, sizeof(viz));
	for (i = 1; i <= n; i++)
		cst[i] = inf;
}

inline int min(int a, int b) {
	if (a < b)
		return a;
	return b;
}

int bford() {
	int q[maxn * maxn], p, u, nod, fiu, fl;
	cst[s] = 0; flux[s] = inf;
	p = u = 1;
	q[1] = s; viz[s] = 1;

	while (p <= u) {
		nod = q[p];
		viz[nod] = 0;
		for (j = 0; j < v[nod].size(); j++) {
			fiu = v[nod][j];
			if (c[nod][fiu] - f[nod][fiu] > 0 && cst[fiu] > cst[nod] + z[nod][j]) {
				cst[fiu] = cst[nod] + z[nod][j];
				up[fiu] = nod;
				if (viz[fiu] == 0) {
					u++;
					q[u] = fiu;
					viz[fiu] = 1;
				}
			}
		}
		p++;
	}

	if (cst[d] != inf) {
//		fprintf(stderr, "%d\n", cst[d]);
		ok = 1;
		fl = inf;
		for (i = d; i != s; i = up[i])
			fl = min(fl, c[up[i]][i] - f[up[i]][i]);

		for (i = d; i != s; i = up[i]) {
			f[up[i]][i] += fl;
			f[i][up[i]] -= fl;
		}

//		fprintf(stderr, "%d\n", fl * cst[d]);
		return fl * cst[d];
	}

	return 0;
}

int main() {
	freopen("fmcm.in", "r", stdin);
	freopen("fmcm.out", "w", stdout);

	scanf("%d%d%d%d", &n, &m, &s, &d);
	for (i = 1; i <= m; i++) {
		scanf("%d%d%d%d", &aa, &bb, &cc, &zz);
		v[aa].push_back(bb);
		v[bb].push_back(aa);
		c[aa][bb] = cc;
		z[aa].push_back(zz);
		z[bb].push_back(-zz);
	}

	ok = 1;
	while (ok) {
		init();
		ok = 0;
		rez += bford();
//		fprintf(stderr, "%d\n", rez);
	}

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

	return 0;
}