Cod sursa(job #1053151)

Utilizator superman_01Avramescu Cristian superman_01 Data 12 decembrie 2013 13:34:50
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.46 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] ) ;
    }
    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;
		if ( Dist[node] < Heap.top().first )
			{
				Heap.pop();
				continue;
		}
        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;   
}