Cod sursa(job #928566)

Utilizator ELHoriaHoria Cretescu ELHoria Data 26 martie 2013 15:23:11
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.53 kb
#include <fstream>
#include <vector>
#include <functional>
#include <cstring>
#include <queue>
#define pii pair<int,int>

using namespace std;

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

const int NMAX = 352, inf = int(1e9);
vector<int> G[NMAX];
int N, M, S, D;
int cap[NMAX][NMAX], cost[NMAX][NMAX];
int dist[3][NMAX], dLine, T[NMAX];
int flowCost, maxFlow;
bool inQueue[NMAX];
priority_queue< pii,vector< pii >,greater< pii > > h;
queue<int> q;

void readData() {
	cin>>N>>M>>S>>D;
	int a, b, c, d;
	for(int i = 0;i < M;i++) {
		cin>>a>>b>>c>>d;
		G[a].push_back(b);
		G[b].push_back(a);
		cap[a][b] = c;
		cost[a][b] = d;
		cost[b][a] = -d;
	}
}

bool bellman() {
	for(int i = 1;i <= N;i++) {
		dist[dLine][i] = inf;
	}
	dist[dLine][S] = 0;
	for(q.push(S), inQueue[S] = true;!q.empty();) {
		int v = q.front();
		q.pop();
		inQueue[v] = false;
		for(vector<int>::const_iterator w = G[v].begin();w != G[v].end();w++) {
			if(cap[v][*w] > 0 && dist[dLine][*w] > dist[dLine][v] + cost[v][*w]) {
				dist[dLine][*w] = dist[dLine][v] + cost[v][*w];
				if(!inQueue[*w]) {
					inQueue[*w] = true;
					q.push(*w);
				}
			}
		}
	}
	if(dist[dLine][D] == inf) {
		return false;
	}
	return true;
}
pii djikstra() {
	dLine = 1 - dLine;
	for(int i = 1;i <= N;i++) {
		dist[dLine][i] = dist[2][i] = inf;
	}
	dist[dLine][S] = dist[2][S] = 0;
	h.push(make_pair(0,S));

	while(!h.empty()) {
		int v = h.top().second;
		int currentCost = h.top().first;
		h.pop();
		if(currentCost != dist[2][v]) continue;
		for(vector<int>::const_iterator w = G[v].begin();w != G[v].end();w++) {
			if(cap[v][*w] > 0 && dist[2][*w] > dist[2][v] + cost[v][*w] + dist[1 - dLine][v] - dist[1 - dLine][*w]) {
				dist[2][*w] = dist[2][v] + cost[v][*w] + dist[1 - dLine][v] - dist[1 - dLine][*w];
				T[*w] = v;
				dist[dLine][*w] = dist[dLine][v] + cost[v][*w];
				h.push(make_pair(dist[2][*w],*w));
			}
		}
	}
	if(dist[2][D] == inf) {
		return make_pair(0,0);
	}
	int fmin = inf;
	for(int v = D;v != S;v = T[v]) {
		fmin = min(fmin,cap[T[v]][v]);
	}
	for(int v = D;v != S;v = T[v]) {
		cap[T[v]][v] -= fmin;
		cap[v][T[v]] += fmin;
	}
	return make_pair(fmin,fmin*dist[dLine][D]);
}

pii solve() { //flow,flow cost
	pii ret, current;
	ret.first = ret.second = 0;
	if(bellman()) {
		do {
			current = djikstra();
			ret.first += current.first;
			ret.second += current.second;
		} while(current.second != 0);
	}
	return ret;
}

int main() 
{
	readData();
	cout<<solve().second;
	return 0;
}