Cod sursa(job #920111)

Utilizator paul_gabryelPaul Buda paul_gabryel Data 20 martie 2013 02:18:13
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.27 kb

#include <fstream>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;

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

const int N = 351;

#define oo 0x3f3f3f3f

vector<int> G[N];
int C[N][N],D[N][N],n,m,start,stop,DIST[N],DST[N],F[N],T[N],SOL;
queue<int> Q;
priority_queue<pair<int,int> > H;

void READ ()
{

    in>>n>>m>>start>>stop;

    for( int x,y,cost,cap ; m ; --m )
    {

        in>>x>>y>>cap>>cost;

        G[x].push_back(y);
        G[y].push_back(x);

        C[x][y]=cap;

        D[x][y]=cost;
        D[y][x]=-cost;

    }

}

bool FLOW ()
{

    memset(DST,oo,sizeof(DST));
    DST[start]=0;
    F[start]=0;
    for( H.push(make_pair(0,start)) ; H.size() ; )
    {
        int nod=H.top().second;
        int d=-H.top().first;
        H.pop();
        if( DST[nod] < d )
            continue;
        for( vector<int>::iterator it=G[nod].begin() ; it < G[nod].end() ; ++it )
            if( C[nod][*it] )
            {
                d = DIST[nod]+D[nod][*it]-DIST[*it];
                if( DST[*it] <= DST[nod]+d )
                    continue;
                DST[*it]=DST[nod]+d;
                F[*it]=F[nod]+D[nod][*it];
                T[*it]=nod;
                H.push(make_pair(-DST[*it],*it));
            }
    }

    memcpy(DIST,F,sizeof(F));

    return DST[stop] != oo ;

}

void SOLVE ()
{

    memset(DIST,oo,sizeof(DIST));
    DIST[start]=0;
    for( Q.push(start) ; Q.size() ; Q.pop() )
    {
        int nod=Q.front();
        for( vector<int>::iterator it=G[nod].begin() ; it < G[nod].end() ; ++it )
            if( C[nod][*it] && DIST[*it] > DIST[nod] + D[nod][*it] )
            {
                DIST[*it]=DIST[nod]+D[nod][*it];
                Q.push(*it);
            }
    }

    for( int flow ; FLOW() ; SOL+=flow*F[stop] )
    {

        flow=oo;

        for( int i=stop ; i != start ; i=T[i] )
            if( flow > C[T[i]][i] )
                flow=C[T[i]][i];

        for( int i=stop ; i != start ; i=T[i] )
        {
            C[T[i]][i]-=flow;
            C[i][T[i]]+=flow;
        }

    }

}

void PRINT ()
{

    out<<SOL;

}

int main ()
{

    READ ();
    SOLVE ();
    PRINT ();

    return 0;

}