Cod sursa(job #2820109)

Utilizator Cosmin2004_InfoMoldoveanu Cosmin Cosmin2004_Info Data 19 decembrie 2021 21:46:16
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.9 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
using ll = long long;
using pii = pair <int, int>;
class mcFlow {
    const int inf = 1e9;
    int n, s, t;
    vector <vector <int>> g, cap, cost;
    vector <int> dmin, distn, dist, p, mn;
    void add_edge(int u, int v, int w, int c) {
        g[u].push_back(v);
        g[v].push_back(u);
        cap[u][v] = w;
        cost[v][u] = - (cost[u][v] = c);
    }
    void bellman() {
        fill(dmin.begin(), dmin.end(), inf);
        queue <int> q;
        vector <bool> inq(n + 1, false);
        for(q.push(s), dmin[s] = 0; !q.empty(); q.pop()) {
            int u = q.front();
            inq[u] = false;
            for(int v : g[u]) if(cap[u][v] && dmin[u] + cap[u][v] < dmin[v]) {
                dmin[v] = dmin[u] + cost[u][v];
                if(!inq[v]) {
                    inq[v] = true;
                    q.push(v);
                }
            }
        }
    }
    bool dijkstra() {
        fill(dist.begin(), dist.end(), inf); fill(p.begin(), p.end(), 0); fill(dist.begin(), dist.end(), inf);
        priority_queue <pii> pq;
        for(pq.emplace(0, s), mn[s] = inf, dist[s] = distn[s] = 0; !pq.empty();) {
            int u = pq.top().second, d = -pq.top().first;
            pq.pop();
            if(dist[u] != d) continue;
            for(int v : g[u]) if(cap[u][v] && dist[u] + cost[u][v] + dmin[u] - dmin[v] < dist[v]) {
                distn[v] = distn[u] + cost[u][v];
                dist[v] = dist[u] + cost[u][v] + dmin[u] - dmin[v];
                p[v] = u;
                mn[v] = min(mn[u], cap[u][v]);
                pq.emplace(-dist[v], v);
            }
        }
        for(int i = 1; i <= n; i++) dmin[i] = distn[i];
        return p[t];
    }
public:
    struct edge {
        int u, v, cap, cost;
        edge(int a, int b, int c, int d) : u(a), v(b), cap(c), cost(d) {}
    };
    mcFlow(int _n, int _s, int _t, vector <edge> e) : n(_n), s(_s), t(_t), g(n + 1), cap(n + 1, vector <int> (n + 1, 0)), cost(n + 1, vector <int> (n + 1, 0)), dmin(n + 1), distn(n + 1), dist(n + 1), p(n + 1), mn(n + 1) {
        for(edge ed : e) add_edge(ed.u, ed.v, ed.cap, ed.cost);
        bellman();
    }
    pii flow() {
        ll fcost = 0, flow = 0;
        while(dijkstra()) {
            fcost += 1ll * mn[t] * dmin[t];
            for(int node = t; p[node]; node = p[node])
                cap[node][p[node]] += mn[t],
                cap[p[node]][node] -= mn[t];
            flow += mn[t];
        }
        return {flow, fcost};
    }
};

int main()
{
    vector <mcFlow :: edge> e;
    int n, m, s, t, u, v, w, c;
    fin >> n >> m >> s >> t;
    for(int i = 1; i <= m; i++) {
        fin >> u >> v >> w >> c;
        e.emplace_back(u, v, w, c);
    }
    mcFlow f(n, s, t, e);
    pii flow = f.flow();
    fout << flow.second;
    return 0;
}