Cod sursa(job #2875440)

Utilizator beingsebiPopa Sebastian beingsebi Data 21 martie 2022 17:32:16
Problema Flux maxim de cost minim Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.7 kb
#include <bits/stdc++.h>
using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
// #define f cin
// #define g cout
const int nmax = 360;

vector<int> v[nmax];
int cap[nmax][nmax], flow[nmax][nmax], we[nmax][nmax];
int n, m, source, sink, final_cost, potential[nmax], dp[nmax], realc[nmax], pre[nmax];
void bellman_ford();
bool dijkstra();
int32_t main()
{
    f >> n >> m >> source >> sink;
    for (int x, y, c, d; m; m--)
    {
        f >> x >> y >> c >> d;
        v[x].push_back(y);
        v[y].push_back(x);
        cap[x][y] = c;
        we[x][y] = d;
        cap[y][x] = 0;
        we[y][x] = -d;
    }
    bellman_ford();
    while (dijkstra())
        ;
    g << -final_cost;
    return 0;
}
void bellman_ford()
{
    memset(potential, 0x3f3f3f3f, sizeof potential);
    queue<int> q;
    vector<bool> inq(nmax, false);
    q.push(source);
    potential[source] = 0;
    inq[source] = 1;
    while (!q.empty())
    {
        static int ac, nc;
        ac = q.front();
        inq[ac] = 0;
        q.pop();
        for (const int &i : v[ac])
            if (cap[ac][i])
            {
                nc = potential[ac] + we[ac][i];
                if (nc < potential[i])
                {
                    potential[i] = nc;
                    if (inq[i])
                        continue;
                    inq[i] = 1;
                    q.push(i);
                }
            }
    }
}
bool dijkstra()
{
    memset(dp, 0x3f3f3f3f, sizeof dp);
    realc[source] = dp[source] = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    pq.push({0, source});
    while (!pq.empty())
    {
        static int nod, cst, ne;
        nod = pq.top().second;
        cst = pq.top().first;
        pq.pop();
        if (cst != dp[nod])
            continue;
        for (const int &i : v[nod])
            if (cap[nod][i] - flow[nod][i] > 0)
            {
                ne = dp[nod] + we[nod][i] + potential[nod] - potential[i];
                if (ne < dp[i])
                {
                    dp[i] = ne;
                    realc[i] = realc[nod] + we[nod][i];
                    pre[i] = nod;
                    pq.push({ne, i});
                }
            }
    }
    if (dp[sink] == (0x3f3f3f3f))
        return 0;
    memcpy(potential, realc, sizeof potential);
    int mnm = INT_MAX;
    for (int ax = sink; ax != source; ax = pre[ax])
        mnm = min(mnm, cap[pre[ax]][ax] - flow[pre[ax]][ax]);
    final_cost += mnm * realc[sink];
    for (int ax = sink; ax != source; ax = pre[ax])
    {
        flow[pre[ax]][ax] -= mnm;
        flow[ax][pre[ax]] += mnm;
    }
    return 1;
}