Cod sursa(job #989452)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 25 august 2013 17:24:02
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.99 kb
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <fstream>
using namespace std;
  
const string file = "fmcm";
  
const string infile = file + ".in";
const string outfile = file + ".out";


struct Arc
{
	int dst;
	int cap;
	int flux;
	int cost;
	int p;

	Arc(int dst, int cap, int cost, int p)
	{
		this->dst = dst;
		this->cap = cap;
		this->cost = cost;
		this->flux = 0;
		this->p = p;
	}

};

vector<vector<int> > G;
vector<Arc> arcs;

vector<int> potential;
vector<int> realDist;
vector<int> pozitiveD;


vector<int> dijParent;
vector<int> dijArc;


priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > heap;


int N, M, S, D;
int MinCost;

const int INF = 0x3f3f3f3f;

void Bellman()
{
	potential.resize(N + 1, INF);
	queue<int> Q;
	vector<bool> inQ(N + 1, false);

	Q.push(S);
	potential[S] = 0;
	while(Q.empty() == false)
	{
		int current = Q.front();
		Q.pop();
		inQ[current] = false;
		for(vector<int>::iterator itr = G[current].begin();
			itr != G[current].end();
			itr++)
		{
			if(arcs[*itr].cap - arcs[*itr].flux > 0)
			{
				if(potential[arcs[*itr].dst] >potential[current] + arcs[*itr].cost)
				{
					potential[arcs[*itr].dst] = potential[current] + arcs[*itr].cost;
					if(inQ[arcs[*itr].dst] == false)
					{
						Q.push(arcs[*itr].dst);
						inQ[arcs[*itr].dst] = true;
					}
				}
			}
		}
	}
}



bool Dijkstra()
{

	memset(&pozitiveD[0], 0x3f, sizeof(int) * (N + 1));

	realDist[S] = 0;
	pozitiveD[S] = 0;

	heap.push(make_pair(pozitiveD[S], S));

	while(heap.empty() == false)
	{
		int cst = heap.top().first;
		int current = heap.top().second;
		heap.pop();

		if(pozitiveD[current] != cst) continue;

		for(vector<int>::iterator itr = G[current].begin();
			itr != G[current].end();
			itr++)
		{
			if(arcs[*itr].cap - arcs[*itr].flux > 0)
			{
				int newCost = arcs[*itr].cost + potential[current] - potential[arcs[*itr].dst];

				if(pozitiveD[arcs[*itr].dst] > pozitiveD[current] + newCost)
				{
					pozitiveD[arcs[*itr].dst] = pozitiveD[current] + newCost;
					realDist[arcs[*itr].dst] = realDist[current] + arcs[*itr].cost;

					heap.push(make_pair(pozitiveD[arcs[*itr].dst], arcs[*itr].dst));

					dijParent[arcs[*itr].dst] = current;
					dijArc[arcs[*itr].dst] = *itr;

				}
			}
		}
	}

	memcpy(&potential[0], &realDist[0], sizeof(int) * (N + 1));

	if(pozitiveD[D] == INF) return false;

	return true;
}

int main()
{
	fstream fin(infile.c_str(), ios::in);

	fin >> N >> M >> S >> D;

	G.resize( N + 1);
	arcs.reserve(2 * M );

	for(int i = 0; i < M; i++)
	{
		int x, y, c, z;
		fin >> x >> y >> c >> z;

		G[x].push_back(arcs.size());
		G[y].push_back(arcs.size() + 1);

		Arc to(y, c, z, arcs.size() + 1);
		Arc from(x, 0, -z, arcs.size());

		arcs.push_back(to);
		arcs.push_back(from);

	}
	fin.close();

	Bellman();

	dijParent.resize(N + 1);
	dijArc.resize(N + 1);

	realDist.resize(N + 1);
	pozitiveD.resize(N + 1);

	while(Dijkstra())
	{
		int maxFlow = INF;
		for(int current = D; current != S; current = dijParent[current])
		{
			maxFlow = min(maxFlow, arcs[dijArc[current]].cap - arcs[dijArc[current]].flux); 
		}

		for(int current = D; current != S; current = dijParent[current])
		{
			arcs[dijArc[current]].flux += maxFlow;
			arcs[arcs[dijArc[current]].p] .flux -= maxFlow; 
		}
		
		MinCost += maxFlow * realDist[D];
		//cout << MinCost << "\n";
	}

	fstream fout(outfile.c_str(), ios::out);
	fout << MinCost << "\n";
	cout << MinCost << "\n";
	fout.close();
}