Cod sursa(job #3042080)

Utilizator Cosmin2004_InfoMoldoveanu Cosmin Cosmin2004_Info Data 3 aprilie 2023 21:37:29
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.48 kb
#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 5;
struct edge {
    int from, to, cap, cost;
};
vector <int> g[N];
vector <edge> e;
int n, m, s, t;
using ll = long long;
const ll inf = 1e18;
void add_edge(int u, int v, int w, int c) {
    g[u].push_back(e.size());
    e.push_back({u, v, w, c});
    g[v].push_back(e.size());
    e.push_back({v, u, 0, -c});
}
bool inq[N];
ll d[N];
void bellman() {
    queue <int> q;
    q.push(s);
    fill(d, d + n + 1, inf);
    d[s] = 0;
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        inq[u] = false;
        for(int id : g[u]) {
            int v = e[id].to;
            if(d[v] > d[u] + e[id].cost && e[id].cap) {
                d[v] = d[u] + e[id].cost;
                if(!inq[v]) {
                    q.push(v);
                    inq[v] = true;
                }
            }
        }
    }
}
struct heapn {
    ll dist;
    int u;
    friend bool operator <(const heapn& a, const heapn& b) {
        return a.dist < b.dist;
    }
};
ll dist[N];
int from[N];
bool dijkstra() {
    priority_queue <heapn> pq;
    fill(dist, dist + n + 1, inf);
    fill(from, from + n + 1, -1);
    pq.push({0, s});
    dist[s] = 0;
    while(!pq.empty()) {
        auto [dd, u] = pq.top();
        pq.pop();
        if(dd != dist[u]) continue;
        for(int id : g[u]) {
            int v = e[id].to;
            if(e[id].cap && dist[v] > d[u] - d[v] + dist[u] + e[id].cost) {
                dist[v] = d[u] - d[v] + dist[u] + e[id].cost;
                from[v] = id;
                pq.push({dist[v], v});
            }
        }
    }
    for(int i = 1; i <= n; i++) {
        d[i] = min(d[i] + dist[i], inf);
    }
    return from[t] != -1;
}

int main()
{
#ifndef HOME
    ifstream cin("fmcm.in");
    ofstream cout("fmcm.out");
#endif
    ios_base :: sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n >> m >> s >> t;
    for(int i = 0, u, v, w, c; i < m; i++)
        cin >> u >> v >> w >> c,
        add_edge(u, v, w, c);
    ll flow = 0, cost = 0;
    bellman();
    while(dijkstra()) {
        int c = 1e9;
        for(int i = from[t]; i != -1; i = from[e[i].from]) {
            c = min(c, e[i].cap);
        }
        for(int i = from[t]; i != -1; i = from[e[i].from]) {
            cost += c * e[i].cost;
            e[i].cap -= c;
            e[i ^ 1].cap += c;
        }
        flow += c;
    }
    cout << cost;
    return 0;
}