Cod sursa(job #2875443)

Utilizator beingsebiPopa Sebastian beingsebi Data 21 martie 2022 17:33:34
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.31 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;
struct edge
{
    int to, capacity, flow, weight, residual;
    int remaining_capacity() const
    {
        return capacity - flow;
    }
    edge(int _to, int _cap, int _flow, int _we, int _res)
    {
        to = _to;
        capacity = _cap;
        flow = _flow;
        weight = _we;
        residual = _res;
    }
};
vector<edge> v[nmax];
int n, m, source, sink, final_cost, potential[nmax], dp[nmax], realc[nmax];
pair<int, int> pre[nmax]; // nod,poz
void bellman_ford();
bool dijkstra();
int32_t main()
{
    f >> n >> m >> source >> sink;
    for (int x, y, c, d, ax1, ax2; m; m--)
    {
        f >> x >> y >> c >> d;
        ax1 = v[y].size();
        ax2 = v[x].size();
        v[x].push_back(edge(y, c, 0, d, ax1));
        v[y].push_back(edge(x, 0, 0, -d, ax2));
    }
    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 edge &i : v[ac])
            if (i.capacity)
            {
                nc = potential[ac] + i.weight;
                if (nc < potential[i.to])
                {
                    potential[i.to] = nc;
                    if (inq[i.to])
                        continue;
                    inq[i.to] = 1;
                    q.push(i.to);
                }
            }
    }
}
bool dijkstra()
{
    memset(dp, 0x3f3f3f3f, sizeof dp);
    // memset(realc, 0x3f3f3f3f, sizeof realc);
    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, ur;
        nod = pq.top().second;
        cst = pq.top().first;
        pq.pop();
        if (cst != dp[nod])
            continue;
        for (int i = 0; i < (int)v[nod].size(); i++)
            if (v[nod][i].remaining_capacity())
            {
                ur = v[nod][i].to;
                ne = dp[nod] + v[nod][i].weight + potential[nod] - potential[ur];
                if (ne < dp[ur])
                {
                    dp[ur] = ne;
                    realc[ur] = realc[nod] + v[nod][i].weight;
                    pre[ur] = {nod, i};
                    pq.push({ne, ur});
                }
            }
    }
    if (dp[sink] == (0x3f3f3f3f))
        return 0;
    memcpy(potential, realc, sizeof potential);
    int mnm = INT_MAX;
    for (int ax = sink; ax != source; ax = pre[ax].first)
        mnm = min(mnm, v[pre[ax].first][pre[ax].second].remaining_capacity());
    final_cost += mnm * realc[sink];
    for (int ax = sink, re, pr; ax != source; ax = pre[ax].first)
    {
        v[pre[ax].first][pre[ax].second].flow -= mnm;
        re = v[pre[ax].first][pre[ax].second].to;
        pr = v[pre[ax].first][pre[ax].second].residual;
        v[re][pr].flow += mnm;
    }
    return 1;
}