Cod sursa(job #2386147)

Utilizator VadimCCurca Vadim VadimC Data 22 martie 2019 11:46:29
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.25 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

#define pii pair<int, int>
#define mp make_pair

#define NMax 360
const unsigned int inf = (1 << 30) - 1;

int n, m, S, D;
int c[NMax][NMax];
int z[NMax][NMax];
vector<int> G[NMax];

int real_d[NMax], old_d[NMax], d[NMax];
int viz[NMax];

int fc;

priority_queue<pii, vector< pii >, greater< pii > > heap;

void init();
void bellman_ford();
bool dijkstra();

int main(){
	init();
	bellman_ford();
	while(dijkstra());
	fout << fc;
}

void init(){
	int i;
	int x, y, cap, cost;
	fin >> n >> m >> S >> D;
	for(i = 0; i < m; i++){
		fin >> x >> y >> cap >> cost;
		c[x][y] = cap;
		z[x][y] = cost;
		z[y][x] = -cost;
		G[x].push_back(y);
		G[y].push_back(x);
	}
}

void bellman_ford(){
	int i, x, v;
	queue<int> q;
	vector<bool> inq(NMax, false);
	for(i = 1; i <= n; i++) real_d[i] = inf;
	real_d[S] = 0;
	q.push(S);
	while(q.size()){
		x = q.front(); q.pop();
		inq[x] = false;
		for(i = 0; i < G[x].size(); i++){
			v = G[x][i];
			if(c[x][v] && real_d[v] > real_d[x] + z[x][v]){
				real_d[v] = real_d[x] + z[x][v];
				if(!inq[v] && v != D){
					q.push(v);
					inq[v] = true;
				}
			}
		}
	}
//	for(i = 1; i <= n; i++) cout << real_d[i] << ' ';
//	cout << endl;
}

bool dijkstra(){
	int i, k;
	int cst, x, v;
	int new_d;
	int fmin;
	for(i = 1; i <= n; i++){
		old_d[i] = real_d[i];
		d[i] = inf;
	}
	d[S] = 0;
	heap.push(mp(d[S], S));
	while(heap.size()){
		cst = heap.top().first; x = heap.top().second; heap.pop();
		if(d[x] != cst) continue;
		for(i = 0; i < G[x].size(); i++){
			v = G[x][i];
			if(c[x][v]){
				new_d = d[x] + z[x][v] + old_d[x] - old_d[v];
				if(new_d < d[v]){
					d[v] = new_d;
					heap.push(mp(new_d, v));
					viz[v] = x;
					real_d[v] = real_d[x] + z[x][v];
				}
			}
		}
	}
	
	if(d[D] == inf) return false;
	
	fmin = inf;
	for(x = D; x != S; x = viz[x]){
		fmin = min(fmin, c[viz[x]][x]);
	}
	
	for(x = D; x != S; x = viz[x]){
		c[viz[x]][x] -= fmin;
		c[x][viz[x]] += fmin;
	}
	
	fc += real_d[D] * fmin;
	
	return true;
}