Cod sursa(job #973493)

Utilizator tudorv96Tudor Varan tudorv96 Data 14 iulie 2013 16:54:36
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.07 kb
#include <fstream>
#include <queue>
#include <list>
using namespace std;
 
ifstream fin ("fmcm.in");
ofstream fout ("fmcm.out");
 
#define oo 0x3f3f3f3f
#define min(a,b) ((a < b) ? a : b)
#define N 355
 
vector <list <int> > g;
vector <vector <int> > C, cost;
vector <int> ci, cr, dr, t;
vector <bool> q;
priority_queue <pair <int, int>, vector <pair <int, int> >, greater <pair <int, int> > > H;
queue <int> Q;
int n, m, sol, s, d;
 
inline 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);
				}
			}
	}
}
 
inline bool dijkstra() {
	ci.assign(n+1, 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);
}

void Resizeall(int x) {
	q.resize(x);
	C.resize(x);
	g.resize(x);
	cr.resize(x);
	ci.resize(x);
	dr.resize(x);
	t.resize(x);
	cost.resize(x);
	for (int i = 1; i < x; ++i)
		C[i].resize(x), cost[i].resize(x);
}
 
int main() {
	fin >> n >> m >> s >> d;
	Resizeall(n+1);
	dr.assign(n+1, 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()) {
		dr = cr;
		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();
}