Cod sursa(job #973413)

Utilizator tudorv96Tudor Varan tudorv96 Data 14 iulie 2013 14:50:42
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.9 kb
#include <fstream>
#include <list>
#include <fstream>
#include <queue>
using namespace std;

ifstream fin ("fmcm.in");
ofstream fout ("fmcm.out");

#define oo (1 << 30)
#define min(a,b) ((a < b) ? a : b)
#define N 355

vector <list <int> > g;
int C[N][N], cost[N][N], ci[N], cr[N], t[N], dr[N], n, m, s, d, sol;
vector <bool> q;
priority_queue <pair <int, int>, vector <pair <int, int> >, greater <pair <int, int> > > H;
queue <int> Q;

void bellmanford() {
	Q.push(s);
	q[s] = 1;
	dr[s] = 0;
	while (Q.size()) {
		int x = Q.front();
		Q.pop();
		for (list <int> :: iterator it = g[x].begin(); it != g[x].end(); ++it)
			if (C[x][*it] && dr[x] + cost[x][*it] < dr[*it]) {
				dr[*it] = dr[x] + cost[x][*it];
				if (!q[*it]) {
					q[*it] = 1;
					Q.push(*it);
				}
			}
	}
}

bool dijkstra() {
	for (int i = 1; i <= n; ++i)
		ci[i] = oo;
	cr[s] = ci[s] = 0;
	H.push(make_pair (0, s));
	while (H.size()) {
		pair <int, int> crt = H.top();
		H.pop();
		if (crt.first > ci[crt.second])
			continue;
		for (list <int> :: iterator it = g[crt.second].begin(); it != g[crt.second].end(); ++it) {
			int opt = ci[crt.second] + cost[crt.second][*it] + dr[crt.second] - dr[*it];
			if (C[crt.second][*it] && opt < ci[*it]) {
				ci[*it] = opt;
				cr[*it] = cr[crt.second] + cost[crt.second][*it];
				H.push(make_pair (ci[*it], *it));
				t[*it] = crt.second;
			}
		}
	}
	return (ci[d] != oo);
}

int main() {
	fin >> n >> m >> s >> d;
	q.resize(n+1);
	g.resize(n+1);
	for (int i = 1; i <= n; ++i)
		dr[i] = oo;
	while (m--) {
		int x, y, c, z;
		fin >> x >> y >> c >> z;
		C[x][y] = c;
		cost[x][y] = z;
		cost[y][x] = -z;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	fin.close();
	bellmanford();
	while (dijkstra()) {
		int flux = oo;
		for (int x = d; x != s; x = t[x])
			flux = min(flux, C[t[x]][x]);
		sol += flux * cr[d];
		for (int x = d; x != s; x = t[x]) {
			C[t[x]][x] -= flux;
			C[x][t[x]] += flux;
		}
	}
	fout << sol;
	fout.close();
}