Cod sursa(job #1712226)

Utilizator Mr.RobotElliot Alderson Mr.Robot Data 2 iunie 2016 12:34:06
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.3 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstdio>
#include <cassert>
#include <stdlib.h>
#include <cstring>
using namespace std;

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

#define N 352
#define mult 2000000000

vector < int > l[N];
int n, m, s, d, x, y, z, w, old_dist[N], cap[N][N], cost[N][N], dist[N], real_dist[N], tata[N], flow[N][N];
bool inq[N];
queue < int > q;
vector < pair < int, int > > heap;

int DIJK()
{
    for( int i = 1; i <= n; ++ i )
        dist[i] = mult;

    heap.push_back( make_pair( 0, s ) );
    dist[s] = 0;
    make_heap( heap.begin(), heap.end() );

    while( !heap.empty() )
    {
        pop_heap( heap.begin(), heap.end() );
        int nod = heap.back().second;
        int dis = -heap.back().first;
        heap.pop_back();

        if( dist[nod] != dis)
            continue;

        for( vector < int > :: iterator it = l[nod].begin(); it != l[nod].end(); ++ it )
        {
            if( cap[nod][*it] > flow[nod][*it] )
            {
                int niu = dist[nod] + cost[nod][*it] + old_dist[nod] - old_dist[*it];
                if( niu < dist[*it] )
                {
                    dist[*it] = niu;
                    real_dist[*it] = real_dist[nod] + cost[nod][*it];
                    if( *it != d )
                    {
                        heap.push_back( make_pair( -niu, *it) );
                        push_heap( heap.begin(), heap.end() );
                    }
                    tata[*it] = nod;
                }
            }
        }
    }
    for( int i = 1; i <= n; ++ i )
        old_dist[i] = real_dist[i];

    if( dist[d] == mult )
        return 0;
    return 1;
}

void BELLMAN()
{
   for( int i = 1; i <= n; ++ i )
        old_dist[i] = mult;
    old_dist[s] = 0;
    q.push(s);
    inq[s] = true;

    while( !q.empty() )
    {
        int x = q.front();
        inq[x] = 0;
        q.pop();
        for( vector < int > :: iterator it = l[x].begin(); it != l[x].end(); ++ it )
        {
            if( cap[x][*it] )
            {
                if( old_dist[x] + cost[x][*it] < old_dist[*it] )
                {
                    dist[*it] = dist[x] + cost[x][*it];
                    if( inq[*it] == 0 )
                    {
                        inq[*it] = 1;
                        q.push(*it);
                    }
                }
            }
        }
    }
}


int main()
{
    int max_flux = 0, flux;
    in >> n >> m >> s >> d;

    for( int i = 0; i < m; ++ i )
    {
        in >> x >> y >> z >> w;
        l[x].push_back(y);
        l[y].push_back(x);
        cap[x][y] = z;
        cost[x][y] = w;
        cost[y][x] = -w;
    }

    BELLMAN();

    while( DIJK() )
    {
        int fmin = mult;

        for( int aux = d; tata[aux]; aux = tata[aux] )
        {
            if( cap[tata[aux]][aux] - flow[tata[aux]][aux] < fmin )
                fmin = cap[tata[aux]][aux] - flow[tata[aux]][aux];
        }
        for( int aux = d; tata[aux]; aux = tata[aux] )
        {
            flow[tata[aux]][aux] += fmin;
            flow[aux][tata[aux]] -= fmin;
        }

        max_flux += fmin * old_dist[d];
    }

    out << max_flux;
    return 0;
}