Cod sursa(job #973478)

Utilizator tudorv96Tudor Varan tudorv96 Data 14 iulie 2013 16:35:09
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.06 kb
#include <fstream>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;

#define N 355
#define oo (1 << 30)
#define xx first
#define yy second

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

typedef pair <int, int> data;
typedef pair <data, data> tada;

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

inline bool dijkstra() {
	while (H.size())
		H.pop();
	for (int i = 1; i <= n; ++i) 
		ci[i] = oo, MIN[i] = oo;
	MIN[s] = 0;
	H.push(tada (data (0, 0), data (s, s)));
	while (H.size() && ci[d] == oo) {
		tada crt = H.top();
		H.pop();
		if (ci[crt.yy.xx] != oo)
			continue;
		ci[crt.yy.xx] = crt.xx.xx;
		cr[crt.yy.xx] = crt.xx.yy;
		t[crt.yy.xx] = crt.yy.yy;
		for (vector <int> :: iterator it = g[crt.yy.xx].begin(); it != g[crt.yy.xx].end(); ++it) {
			int opt = ci[crt.yy.xx] + cost[crt.yy.xx][*it] + dr[crt.yy.xx] - dr[*it];
			if (c[crt.yy.xx][*it] && opt < MIN[*it]) {
				MIN[*it] = opt;
				H.push (tada (data (opt, cr[crt.yy.xx] + cost[crt.yy.xx][*it]), data(*it, crt.yy.xx)));
			}
		}
	}
	return (ci[d] != oo);
}

inline void bellmanford() {
	q[s] = 1;
	Q.push(s);
	dr[s] = 0;
	while (Q.size()) {
		int x = Q.front();
		Q.pop();
		for (vector <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);
				}
			}
	}
}
		

int main () {
	fin >> n >> m >> s >> d;
	while (m--) {
		int x, y, f, z;
		fin >> x >> y >> f >> z;
		c[x][y] = f;
		cost[x][y] = z;
		cost[y][x] = -z;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	fin.close();
	for (int i = 1; i <= n; ++i)
		dr[i] = oo;
	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;
		}
		for (int i = 1; i <= n; ++i)
			dr[i] = cr[i];
	}
	fout << sol;
}