Cod sursa(job #1052896)

Utilizator superman_01Avramescu Cristian superman_01 Data 11 decembrie 2013 21:30:23
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <iostream>

#define MAX_SIZE 355
#define TYPE pair < int , int > 
#define INF 0x3f3f3f3f
#define get_min(a,b) ((a)>(b)?(b):(a))
#define get_max(a,b) ((a)>(b)?(a):(b))

using namespace std;

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

typedef  vector < int > ::iterator IT ;
vector < int > G[MAX_SIZE];
priority_queue < TYPE , vector < TYPE > , greater < TYPE > > Heap;
int Dist[MAX_SIZE] , Answer , From[MAX_SIZE];
int N , M , S , D , Cost[MAX_SIZE][MAX_SIZE] , Cap[MAX_SIZE][MAX_SIZE] , Flow[MAX_SIZE][MAX_SIZE];
queue < int > Q;
bool InQ[MAX_SIZE] , PathFlow;

void Initialize ( int Start )
{
	for ( int i = 1 ; i <= N ; ++i )
	{
		for ( IT it = G[i].begin() ; it != G[i].end() ; ++it  )
			if ( Dist[i] != INF and Dist[*it] != INF )
				Cost[i][*it] += ( Dist[i] - Dist[*it] ) ;
	}
	for(;!Heap.empty(); Heap.pop());
	memset( From , 0 , sizeof (From) );
	memset ( Dist , INF , sizeof ( Dist ) );
	Dist[Start] = 0 ;
    
}

bool Dijkstra ( int Start , int Finish )
{
	Initialize(Start);
	Heap.push(make_pair(0,Start));
	for(;!Heap.empty();)
	{
     	int node = Heap.top().second;
		Heap.pop();
		for ( IT it = G[node].begin() ;  it != G[node].end() ; ++it )
		{
			int newnode = *it ;
			int cost = Cost[node][newnode];
			if ( Dist[newnode] > Dist[node] + cost and Cap[node][newnode] - Flow[node][newnode] ) 
			{
				Dist[newnode] = Dist[node] + cost;
				From[newnode] = node ;
				Heap.push(make_pair ( Dist[newnode] , newnode));
			}
		}		
	}	
	return ( Dist[Finish] < INF ) ;
}


void BellmanFord ( void )
{
	Q.push(S);
	memset ( Dist , INF , sizeof ( Dist) );
	memset ( InQ , false , sizeof ( InQ) );
	Dist[S] = 0;
	InQ[S] = true ;
	for ( ;!Q.empty(); )
	{
		int node = Q.front();
		Q.pop();
		InQ[node] = false ;
		for ( IT it = G[node].begin() ; it != G[node].end() ; ++it )
			if ( Cap[node][*it] and Dist[node] + Cost[node][*it] < Dist[*it]  )
		{
			Dist[*it] = Dist[node] + Cost[node][*it] ;
			if ( !InQ[*it] )
			{
				Q.push ( *it );
				InQ[*it] = true ;
			}
		}
	}
}

void EdmondsKarp ( void )
{
	BellmanFord();
	int Special_Distance = Dist[D] ;
	while( Dijkstra ( S ,D) )
	{
		int CurrentFlow = INF ;
		for ( int node = D ; node != S ; node = From[node] )
			CurrentFlow = get_min ( CurrentFlow , Cap[From[node]][node] - Flow[From[node]][node] );
		for ( int node = D ; node != S ; node = From[node] )
		{
			Flow[From[node]][node] += CurrentFlow;
			Flow[node][From[node]] -= CurrentFlow;
		}
	    Special_Distance += Dist[D] ;
		Answer += ( CurrentFlow*Special_Distance );
	}
}
int main ( void )
{
	int i , j , x , y , cost , cap;
	in >> N >> M >> S >> D ;
	for ( i = 1 ; i <= M ; ++i )
	{
		in >> x >> y >> cap >> cost;
		G[x].push_back(y);
		G[y].push_back(x);
		Cap[x][y] = cap;
		Cost[x][y] = cost ;
		Cost[y][x] = -cost;
	}
	EdmondsKarp();
	out << Answer << "\n";
	in.close();
	out.close();
	return 0;	
}