Cod sursa(job #2370302)

Utilizator akaprosAna Kapros akapros Data 6 martie 2019 11:33:37
Problema Flux maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.46 kb
#include <bits/stdc++.h>
#define max 352

using namespace std;

FILE *fin = freopen("fmcm.in", "r", stdin);
FILE *fout = freopen("fmcm.out", "w", stdout);

int n, m, S, D;

int r[maxN][maxN], cost[maxN][maxN];
int old_d[maxN], d[maxN], real_d[maxN];
vector < int > G[maxN];

int Flow, FlowCst;

void AddEdge(int u, int v, int cap, int cst)
{
    r[u][v] = cap;
    cost[u][v] = cst;
    cost[v][u] = -cst;
}
inline bool Dijkstra()
{
    memset(d, c1, sizeof(d));
    d[S] = real_d[S] = 0;
    H.push(pii{d[S], S});
    while (!H.empty())
    {
        pii x = H.top();
        H.pop();
        int nod = x.second;
        if (d[nod] != x.first)
            continue;

        for (int adj : G[nod])
            if (r[nod][adj])
            {
                int newD = d[nod] + cost[nod][adj] + old_d[nod] - old_d[adj];
                if (newD < d[adj])
                {
                    d[adj] = newD;
                    real_d[adj] = real_d[nod] + cost[nod][adj];
                    H.push_back(pii{newD, adj});
                    prv[adj] = nod;
                }
            }
    }
    memcpy(old_d, real_d, sizeof(real_d));
    if (d[D] == inf)
        return false;

    int Min = inf, crtCost = 0, nod = D;
    while (nod != S)
    {
        crtCos += cost[prv[nod]][nod];
        Min = min(Min, r[prv[nod]][nod]);
        nod = prv[nod];
    }
    nod = D;
    while (nod != S)
    {
        r[prv[nod]][nod] -= Min;
        r[nod][prv[nod]] += Min;
        nod = prv[nod];
    }
    Flow += Min;
    FlowCost += Min * real_d[D];
}
inline bool BellmanFord()
{
    memset(old_d, c1, sizeof(old_d));
    inQ[S] = 1;
    Q.push(S);
    while (!Q.empty())
    {
        int nod = Q.front();
        Q.pop();
        inQ[nod] = 0;
        for (adj : G[nod])
            if (r[nod][adj] && old_d[nod] + cost[nod][adj] < old_d[adj])
            {
                old_d[adj] = old_d[nod] + cost[nod][adj];
                if (!inQ[adj])
                {
                    inQ[adj] = 1;
                    Q.push(adj);
                }
            }
    }
    return (old_d[D]] != inf);
}
int main()
{
    scanf("%d%d%d%d", &n, &m, &S, &D);
    while (m --)
    {
        int x, y, cap, cst;
        scanf("%d%d%d%d", &x, &y, &cap, &cst);
        AddEdge(x, y, cap, cst);
    }
    Flow = 0;
    FlowCst = 0;

    BellmanFord();
    for (; Dijkstra(); );
    printf("%d\n", FlowCost);
    return 0;
}