Cod sursa(job #742658)

Utilizator valentin.harsanValentin Harsan valentin.harsan Data 30 aprilie 2012 22:57:28
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.61 kb
#include<iostream>
#include<fstream>
#include<vector>
#include<queue>
#include<string.h>
#include<queue>
using namespace std;

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

const int N = 351;

struct muc {
	int a, b, c, ci;
};

class cmp {
public:
	bool operator()(muc a, muc b) {
		return a.c + a.ci < b.c + b.ci;
	}
};

int n, m, cap[N][N], f[N][N], c[N][N], s, d, drum, dist[N], p[N], sum;
vector<int> v[N];
priority_queue<muc, vector<muc>, cmp> h;

void bf() {
	vector<int>::iterator it;
	queue<int> q;
	int el, i;
	bool ver[N];
	
	memset(ver, false, sizeof(ver));
	
	for(i = 1; i<=n; ++i)
		dist[i] = (int)1<<25;
	
	q.push(s);
	dist[s] = 0;
	
	while(!q.empty()) {
		el = q.front();
		q.pop();
		
		for(it = v[el].begin(); it!=v[el].end(); ++it)
			if(cap[el][*it] - f[el][*it] > 0 && dist[el] + c[el][*it] < dist[*it]) {
				
				dist[*it] = dist[el] + c[el][*it];
				
				if(!ver[*it]) {
					ver[*it] = true;
					q.push(*it);
				}
			}
		
		ver[el] = true;
	}
	
	sum = dist[d];
}

int djk() {
	int i,vmin = 1<<25, j;
	vector<int>::iterator it;
	muc t;
	
	for(i = 1; i<=n; ++i)
		for(it = v[i].begin(); it!= v[i].end(); ++it)
			if(dist[i] != (1<<25) && dist[*it] != (1<<25))
				c[i][*it] += dist[i] - dist[*it];
	
	for(i = 1; i<=n; ++i) {
		dist[i] = 1<<25;
		p[i] = -1;
	}
	
	t.a = s;
	for(it = v[s].begin(); it!=v[s].end(); ++it) if(cap[s][*it] - f[s][*it] > 0) {
		t.b = *it; t.c = c[s][*it];
		h.push(t);
	}
	
	dist[s] = 0;
	
	while(!h.empty()) {
		while(!h.empty() && dist[h.top().b]<=dist[h.top().a] + h.top().c)
			h.pop();
		if(h.empty())
			break;
		
		t = h.top();
		dist[t.b] = dist[t.a] + t.c;
		t.ci = dist[t.b];
		p[t.b] = t.a;
		t.a = t.b;
		int tt = h.top().b;
		h.pop();
		for(j = 0; j!=v[tt].size(); ++j) 
			if(cap[tt][v[tt][j]] - f[tt][v[tt][j]] > 0) {
				t.b = v[tt][j];
				t.c = c[t.a][t.b];
			
				h.push(t);
			}
	}
	
	if(dist[d]!=(1<<25)) {
		
		drum = 1;
		
		for(i = d; i!=s; i = p[i])
			if(cap[p[i]][i] - f[p[i]][i] < vmin)
				vmin = cap[p[i]][i] - f[p[i]][i];
		
		for(i = d; i!=s; i = p[i]) {
			
			f[p[i]][i] += vmin;
			f[i][p[i]] -= vmin;
		}
		
		sum += dist[d];
		return vmin * sum;
	}
	return 0;
}

long long cost() {
	long long cost = 0;
	drum = 1;
	
	while(drum) {
		
		drum = 0;
		cost += djk();
	}
	
	return cost;
}

int main() {
	int i, a, b, lc, co;
	
	in >> n >> m >> s >> d;
	
	for(i = 1; i<=m; ++i) {
		
		in >> a >> b >> lc >> co;
		
		cap[a][b] = lc;
		c[a][b] = co;
		v[a].push_back(b);
	}
	
	bf();
	
	out << cost() << "\n";
	
	return 0;
}