Cod sursa(job #303922)

Utilizator scvalexAlexandru Scvortov scvalex Data 10 aprilie 2009 15:21:45
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

#define pb push_back
#define tr(C, i) for (typeof((C).begin()) i = (C).begin(); i != (C).end(); ++i)

typedef pair<int, int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;

const int oo = 1<<30;

int N;
VVI G, C, F, W;
VI P, D;

bool bfs(int S, int T) {
	fill(P.begin(), P.end(), 0);
	
	queue<int> Q;
	Q.push(S);
	P[S] = S;

	while (!Q.empty()) {
		int u = Q.front();
		Q.pop();

		tr(G[u], vv) {
			int v = *vv;
			
			if (!P[v] && (C[u][v] - F[u][v] > 0)) {
				P[v] = u;
				if (v == T)
					return true;
				Q.push(v);
			}
		}
	}
	return false;
}

bool bf(int S, int T) {
	fill(P.begin(), P.end(), 0);

	queue<int> Q;
	Q.push(S);
	P[S] = S;

	fill(D.begin(), D.end(), oo);
	D[S] = 0;

	while (!Q.empty()) {
		int u = Q.front();
		Q.pop();

		tr(G[u], vv) {
			int v = *vv;
			if ((C[u][v] - F[u][v] > 0) && (D[u] + W[u][v] < D[v])) {
				P[v] = u;
				D[v] = D[u] + W[u][v];
				Q.push(v);
			}
		}
	}

	return (P[T] != 0);
}

int main(int argc, char *argv[]) {
	int M, S, T;
	int u, v, cap, cost;

	ifstream fin("fmcm.in");
	fin >> N >> M >> S >> T;
	G.resize(N+1);
	C.resize(N+1);
	fill(C.begin(), C.end(), VI(N+1, 0));
	W.resize(N+1);
	fill(W.begin(), W.end(), VI(N+1, 0));
	while (M--) {
		fin >> u >> v >> cap >> cost;
		G[u].pb(v);
		C[u][v] = cap;
		W[u][v] = cost;
		G[v].pb(u);
		W[v][u] = -cost;
	}
	fin.close();

	D.resize(N+1);
	F.resize(N+1);
	fill(F.begin(), F.end(), VI(N+1, 0));
	P.resize(N+1);
	int f = 0;
	int ct = 0;
	while (bf(S, T)) {
		int fmin = oo;

		for (int n = T; P[n] != n; n = P[n])
			fmin = min(fmin, C[P[n]][n] - F[P[n]][n]);
		f += fmin;

		for (int n = T; P[n] != n; n = P[n]) {
			F[P[n]][n] += fmin;
			F[n][P[n]] -= fmin;
		}

		ct += fmin * D[T];
	}

	ofstream fout("fmcm.out");
	fout << ct << endl;
	fout.close();

	return 0;
}