Cod sursa(job #1956195)

Utilizator andreigasparoviciAndrei Gasparovici andreigasparovici Data 6 aprilie 2017 16:17:32
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.66 kb
#include <bits/stdc++.h>
using namespace std;

const int SIZE = 351, INF = (1<<30);

int dp[SIZE], tata[SIZE], dst[SIZE], aux[SIZE];
int capacitate[SIZE][SIZE], cost[SIZE][SIZE];

bool mrk[SIZE];
vector<int> graf[SIZE];
queue<int> que;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> heap;

int n, m, s, d;

bool bellman()
{
    fill(dst,dst+SIZE,INF);
    dst[s] = 0;
    fill(mrk, mrk+SIZE,0);
    mrk[s] = 1;
    que.push(s);
    while(!que.empty())
    {
        int x = que.front();
        que.pop();
        mrk[x]=0;
        for( int y : graf[x] )
        {
            if( capacitate[x][y] != 0 && dst[y] > dst[x] + cost[x][y] )
            {
                dst[y] = dst[x] + cost[x][y];
                tata[y] = x;

                if( y != d && !mrk[y])
                {
                    mrk[y] = 1;
                    que.push( y );
                }
            }
        }
    }

    return !(dst[d] == INF);
}

bool dijkstra()
{
    fill(dp,dp + SIZE,INF);
    fill(aux,aux + SIZE,INF);

    dp[s] = aux[s] = 0;
    heap.push(make_pair(0,s));
    while(!heap.empty())
    {
        pair<int, int> x = heap.top();
        heap.pop();

        if( dp[x.second] == x.first)
        {
            for( int y : graf[x.second] )
            {
                if( capacitate[x.second][y] != 0 && \
                   dp[y] > dp[x.second] + dst[x.second] - dst[y] + cost[x.second][y] )
                {
                    dp[y] = dp[x.second] + dst[x.second] - dst[y] + cost[x.second][y];
                    aux[y] = aux[x.second] + cost[x.second][y];
                    tata[y] = x.second;

                    if( y != d )
                        heap.push( make_pair( dp[y], y ) );
                }
            }
        }
    }

    copy(aux,aux+SIZE,dst);

    return !(dp[d]==INF);
}

int main()
{
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);

    scanf( "%d %d %d %d", &n, &m, &s, &d );

    for( int i = 1; i <= m; i ++ )
    {
        int x, y, c, z;
        scanf("%d %d %d %d", &x, &y, &c, &z);

        capacitate[x][y] = c;
        cost[x][y] =  z;
        cost[y][x] = -z;

        graf[x].push_back(y);
        graf[y].push_back(x);
    }

    bellman();

    int cost_min = 0;
    while(dijkstra())
    {
        int minim = INF, i;

        i = d;
        while(i!=s)
        {
            minim = min(minim, capacitate[tata[i]][i]);
            i = tata[i];
        }

        cost_min += dst[d] * minim;

        i = d;

        while(i!=s)
        {
            capacitate[tata[i]][i] -= minim;
            capacitate[i][tata[i]] += minim;
            i = tata[i];
        }
    }

    printf("%d\n",cost_min);
    return 0;
}