Cod sursa(job #1825126)

Utilizator Theodor1000Cristea Theodor Stefan Theodor1000 Data 8 decembrie 2016 19:14:13
Problema Flux maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.92 kb
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <functional>

#define pii pair <int, int>
#define f first
#define s second

using namespace std;

vector <int> v[512];
vector <int> :: iterator it;
int f[512][512], c[512][512], cost[512][512], dij[512], t[512], vir[512], act[512];
int n, m, S, D;
bool ap[512];
queue <int> q;
priority_queue <pii, vector <pii>, greater <pii> > pq;

inline void bellman ()
{
    q.push (S);
    for (; !q.empty (); q.pop ())
    {
        int nod = q.front ();
        t[nod] = 0;

        for (it = v[nod].begin (); it != v[nod].end (); ++it)
            if (c[nod][*it] && dij[nod] + cost[nod][*it] < dij[*it])
            {
                if (!t[*it]) q.push (*it), t[*it] = 1;;
                dij[*it] = dij[nod] + cost[nod][*it];
            }
    }
}

inline bool dijkstra ()
{
    bool OK = false;

    t[S] = -1;
    pq.push ({0, S});
    for (; !pq.empty (); pq.pop ())
    {
        int nod = pq.top ().s;
        if (ap[nod]) continue;
        ap[nod] = true;

        for (it = v[nod].begin (); it != v[nod].end (); ++it)
        {
            if (*it == D) OK = true;
            int val = dij[nod] + cost[nod][*it] - dij[*it];
            if (!ap[*it] && f[nod][*it] < c[nod][*it] && val < vir[*it])
            {
                t[*it] = nod;
                vir[*it] = val;
                act[*it] = act[nod] + cost[nod][*it];
                pq.push ({vir[*it], *it});
            }
        }
    }

    return OK;
}

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, cap, cst;
        scanf ("%d %d %d %d", &x, &y, &cap, &cst);

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

        c[x][y] = cap;
        cost[x][y] = cst;
        cost[y][x] = -cst;
    }

    for (int i = 1; i <= n; ++i)
        dij[i] = 2000000000;
    dij[S] = 0;

    bellman ();

    for (int i = 1; i <= n; ++i)
        t[i] = 0,
        vir[i] = 2000000000,
        ap[i] = false;
    vir[S] = 0;

    int fcost = 0;
    for (; dijkstra ();)
    {
        for (it = v[D].begin (); it != v[D].end (); ++it)
        {
            if (!t[*it]) continue;
            t[D] = *it;

            int nod = D, mi = 2000000000;
            for (; t[nod] != -1; t[nod] = nod)
                mi = min (mi, c[t[nod]][nod] - f[t[nod]][nod]);

            nod = D;
            fcost += mi * act[D];

            if (!mi) continue;
            for (; t[nod] != -1; t[nod] = nod)
                f[t[nod]][nod] += mi,
                f[nod][t[nod]] -= mi;
        }

        for (int i = 1; i <= n; ++i)
            t[i] = 0,
            vir[i] = 2000000000,
            ap[i] = false;
        vir[S] = 0;
    }

    printf ("%d\n", fcost);

    return 0;
}