Cod sursa(job #1658713)

Utilizator sorynsooSorin Soo sorynsoo Data 21 martie 2016 19:06:57
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.17 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <string.h>
using namespace std;
#define MAXN 355
#define INF 0x3f3f3f3f

queue<int> coada;
priority_queue< pair<int, int> > coadaP;
vector<int> graf[MAXN];
int capacitate[MAXN][MAXN], cost[MAXN][MAXN], flux[MAXN][MAXN], dist[MAXN], distF[MAXN], constanta[MAXN], tata[MAXN];
int n, m, st, fin, flux_crt, flux_maxim, cost_crt, cost_maxim;

void bellman(int start, int fin)
{
    int i, crt, urm;
    for(i = 1; i<=n; i++)
        constanta[i] = INF;

    constanta[start] = 0;
    coada.push(start);

    while(!coada.empty())
    {
        crt = coada.front(); coada.pop();
        for(i=0; i<graf[crt].size(); i++)
        {
            urm = graf[crt][i];
            if(constanta[urm] > constanta[crt] + cost[crt][urm] && capacitate[crt][urm] > flux[crt][urm] )
            {
                constanta[urm] = constanta[crt] + cost[crt][urm];
                coada.push(urm);
            }
        }
    }
}

bool dijkstra(int start, int fin)
{
    int i, crt_nod, crt_cost, urm_nod, urm_cost;
    for(i=1; i<=n; i++)
    {
        tata[i] = 0;
        dist[i] = distF[i] = INF;
    }

    dist[start] = distF[start] = 0;
    coadaP.push( make_pair( distF[start], start ));
    while(!coadaP.empty())
    {
        crt_cost = -coadaP.top().first;
        crt_nod = coadaP.top().second;
        coadaP.pop();

        if(distF[crt_nod] != crt_cost)
            continue;

        for(i=0; i<graf[ crt_nod ].size(); i++)
        {
            urm_nod = graf[ crt_nod ][i];

            urm_cost = distF[crt_nod] + cost[crt_nod][urm_nod] + constanta[crt_nod] - constanta[urm_nod];
            if(distF[urm_nod] > urm_cost && capacitate[crt_nod][urm_nod] > flux[crt_nod][urm_nod])
            {
                tata[urm_nod] = crt_nod;
                distF[urm_nod] = urm_cost;
                dist[urm_nod] = dist[crt_nod] + cost[crt_nod][urm_nod];
                coadaP.push( make_pair( -distF[urm_nod], urm_nod ) );
            }
         }
    }

     for(int i=1;i<=n;++i)
        constanta[i]=dist[i];

    if(dist[fin] != INF)
        return 1;

    return 0;

}

int main()
{
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);
    int i, j, x, y, z, w;
    scanf("%d %d %d %d", &n, &m, &st, &fin);
    for(i=1; i<=m; i++)
    {
        scanf("%d %d %d %d", &x, &y, &z, &w);
        graf[x].push_back(y);
        graf[y].push_back(x);
        capacitate[x][y] = z;
        cost[x][y] = w;
        cost[y][x] = -w;
    }

    bellman(st, fin);

    while( dijkstra(st, fin) )
    {
        flux_crt = INF;
        for(i=fin; i!=st; i=tata[i])
            flux_crt = min(flux_crt, capacitate[tata[i]][i] - flux[tata[i]][i]);

        if(flux_crt)
        {
            cost_crt =0;
            for(i=fin; i!=st; i=tata[i])
            {
                flux[tata[i]][i] += flux_crt;
                flux[i][tata[i]] -= flux_crt;
                cost_crt += cost[tata[i]][i];
            }

            flux_maxim += flux_crt;
            cost_maxim += cost_crt*flux_crt;
        }

    }

    printf("%d", cost_maxim);
    return 0;
}