Cod sursa(job #1971497)

Utilizator Burbon13Burbon13 Burbon13 Data 20 aprilie 2017 14:46:41
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.65 kb
#include <cstdio>
#include <vector>
#include <bitset>
#include <queue>

using namespace std;

const int nmx = 355, inf = 0x3f3f3f3f;

int n,m,s,d,cost[nmx][nmx],cap[nmx][nmx],flux[nmx][nmx],rezultat;
vector <int> g[nmx];

void citire()
{
    scanf("%d %d %d %d", &n, &m, &s, &d);
    for(int i = 1; i <= m; ++i)
    {
        int nod1,nod2;
        scanf("%d %d", &nod1, &nod2);
        scanf("%d %d", &cap[nod1][nod2], &cost[nod1][nod2]);
        g[nod1].push_back(nod2);
        g[nod2].push_back(nod1);
        cost[nod2][nod1] = - cost[nod1][nod2];
    }
}

int dist[nmx];

void belmanford()
{
    queue <int> q;
    q.push(s);

    for(int i = 1; i <= n; ++i)
        dist[i] = inf;
    dist[s] = 0;

    while(not q.empty())
    {
        int nod = q.front();
        q.pop();

        for(vector<int>::iterator it = g[nod].begin(); it != g[nod].end(); ++it)
            if(cap[nod][*it] && dist[*it] > dist[nod] + cost[nod][*it])
            {
                dist[*it] = dist[nod] + cost[nod][*it];
                q.push(*it);
            }
    }
}

int disj[nmx],real[nmx],tata[nmx];
priority_queue <pair<int,int> > pq;

bool dijkstra()
{
    for(int i = 1; i <= n; ++i)
        disj[i] = inf;

    disj[s] = 0;
    pq.push({0,s});

    while(not pq.empty())
    {
        int dst = -pq.top().first;
        int nod = pq.top().second;
        pq.pop();

        if(dst != disj[nod])
            continue;

        for(vector<int>::iterator it = g[nod].begin(); it != g[nod].end(); ++it)
        {
            int dpoz = dist[nod] - dist[*it] + cost[nod][*it];
            if(cap[nod][*it] > flux[nod][*it] && disj[*it] > disj[nod] + dpoz)
            {
                disj[*it] = disj[nod] + dpoz;
                real[*it] = real[nod] + cost[nod][*it];
                tata[*it] = nod;
                pq.push({-disj[*it],*it});
            }
        }
    }

    return disj[d] != inf;
}

void rezolvare()
{
    belmanford();

    while(dijkstra())
    {
        int nod = d, minim = inf;

        while(nod != s)
        {
            minim = min(minim, cap[tata[nod]][nod] - flux[tata[nod]][nod]);
            nod = tata[nod];
        }

        nod = d;
        while(nod != s)
        {
            flux[tata[nod]][nod] += minim;
            flux[nod][tata[nod]] -= minim;
            nod = tata[nod];
        }

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

        rezultat += minim * real[d];
    }
}

int main()
{
    freopen("fmcm.in", "r", stdin);
    freopen("fmcm.out", "w", stdout);
    citire();
    rezolvare();
    printf("%d\n", rezultat);
}