Cod sursa(job #989373)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 25 august 2013 15:51:29
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.84 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> pozitiveD;
vector<int> realDist;



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


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()
{
	dijParent.clear();
	dijParent.resize(N + 1);
	dijArc.clear();
	dijArc.resize(N + 1);

	realDist.clear();
	realDist.resize(N + 1, INF);
	realDist[S] = 0;

	pozitiveD.clear();
	pozitiveD.resize(N + 1, INF);
	pozitiveD[S] = 0;

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

	heap.push(make_pair(0, S));

	while(heap.empty() == false)
	{
		int current = heap.top().second;
		heap.pop();
		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;

				}
			}
		}
	}

	potential = realDist;

	if(realDist[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();
	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];
	}

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