Cod sursa(job #1076750)

Utilizator fhandreiAndrei Hareza fhandrei Data 10 ianuarie 2014 15:39:52
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
// Include
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

// Definitii
#define pb push_back

// Constante
const int sz = 351;
const int oo = 0x3f3f3f3f;

// Functii
bool bellmanFord(int *destDist);

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

int nodes, edges, source, destination;
int maxFlow;

int father[sz];

int emptySpace[sz][sz], cost[sz][sz];
vector<int> graph[sz];

// Main
int main()
{
	in >> nodes >> edges >> source >> destination;
	
	int rFrom, rTo, rCapacity, rCost;
	while(edges--)
	{
		in >> rFrom >> rTo >> rCapacity >> rCost;
		graph[rFrom].pb(rTo);
		graph[rTo].pb(rFrom);
		
		emptySpace[rFrom][rTo] = rCapacity;
		
		cost[rFrom][rTo] = rCost;
		cost[rTo][rFrom] = -rCost;
	}
	
	int dist;
	while(bellmanFord(&dist))
	{
		int minFlow = oo;
		
		for(int node=destination ; node!=source ; node=father[node])
			minFlow = min(minFlow, emptySpace[father[node]][node]);
		
		for(int node=destination ; node!=source ; node=father[node])
		{
			emptySpace[father[node]][node] -= minFlow;
			emptySpace[node][father[node]] += minFlow;
		}
		
		maxFlow += dist*minFlow;
	}
	
	out << maxFlow;
	
	in.close();
	out.close();
	return 0;
}

bool bellmanFord(int *destDist)
{
	bool inQueue[sz];
	int dist[sz];
	memset(inQueue, false, sizeof(inQueue));
	memset(father, 0, sizeof(father));
	memset(dist, oo, sizeof(dist));
	
	father[source] = -1;
	dist[source] = 0;
	
	queue<int> bfq;
	bfq.push(source);
	
	while(!bfq.empty())
	{
		int current = bfq.front();
		bfq.pop();
		inQueue[current] = false;
		
		vector<int>::iterator it, end=graph[current].end();
		for(it=graph[current].begin() ; it!=end ; ++it)
		{
			if(!emptySpace[current][*it])
				continue;
			
			if(dist[*it] <= dist[current] + cost[current][*it])
				continue;
			
			dist[*it] = dist[current] + cost[current][*it];
			father[*it] = current;
			
			if(!inQueue[*it])
			{
				bfq.push(*it);
				inQueue[*it] = true;
			}
		}
	}
	
	*destDist = dist[destination];
	return father[destination]? true : false;
}