Cod sursa(job #2695017)

Utilizator stelian2000Stelian Chichirim stelian2000 Data 11 ianuarie 2021 15:21:20
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.97 kb
#include <bits/stdc++.h>

using namespace std;

struct MinCostMaxFlow {
    struct edge {
        int nod, c;
        bool operator < (const edge& aux) const {
            return c > aux.c;
        }
    };

    static const int MAXV = 355;
    static const int inf = 1e9;

    int cap[MAXV][MAXV], dist[MAXV], d[MAXV], newDist[MAXV], tata[MAXV];
    char vaz[MAXV];
    vector<edge> v[MAXV];
    queue<int> q;
    priority_queue<edge> pq;

    void add_edge(int x, int y, int capacity, int cost) {
        v[x].push_back({y, cost});
        v[y].push_back({x, -cost});
        cap[x][y] = capacity;
    }

    void bellman(int sursa, int dest) {
        for (int i = 0; i < MAXV; ++i) dist[i] = inf;
        dist[sursa] = 0;
        vaz[sursa] = 1;
        q.push(sursa);
        while(!q.empty()) {
            int nod = q.front();
            q.pop();
            vaz[nod] = 0;
            for (edge vec : v[nod]) {
                if (cap[nod][vec.nod] > 0 && dist[nod] + vec.c < dist[vec.nod]) {
                    dist[vec.nod] = dist[nod] + vec.c;
                    if (vec.nod != dest && !vaz[vec.nod]) {
                        vaz[vec.nod] = 1;
                        q.push(vec.nod);
                    }
                }
            }
        }
    }

    bool findPath(int sursa, int dest) {
        for (int i = 0; i < MAXV; ++i) d[i] = newDist[i] = inf;
        d[sursa] = newDist[sursa] = 0;
        pq.push({sursa, 0});
        while(!pq.empty()) {
            int nod = pq.top().nod, c = pq.top().c;
            pq.pop();
            if (d[nod] < c) continue;
            for (edge vec : v[nod]) {
                if (cap[nod][vec.nod] > 0 && d[nod] + dist[nod] + vec.c - dist[vec.nod] < d[vec.nod]) {
                    d[vec.nod] = d[nod] + dist[nod] + vec.c - dist[vec.nod];
                    newDist[vec.nod] = newDist[nod] + vec.c;
                    tata[vec.nod] = nod;
                    if (vec.nod != dest) pq.push({vec.nod, d[vec.nod]});
                }
            }
        }
        for (int i = 0; i < MAXV; ++i) dist[i] = newDist[i];
        return d[dest] < inf;
    }

    int flowCost(int sursa, int dest) {
        bellman(sursa, dest);
        int ans = 0;
        while(findPath(sursa, dest)) {
            int s = inf;
            for (int nod = dest; nod != sursa; nod = tata[nod]) s = min(s, cap[tata[nod]][nod]);
            for (int nod = dest; nod != sursa; nod = tata[nod]) {
                cap[tata[nod]][nod] -= s;
                cap[nod][tata[nod]] += s;
            }
            ans += s * dist[dest];
        }
        return ans;
    }
} mcmf;

int main()
{
    freopen("fmcm.in", "r", stdin);
    freopen("fmcm.out", "w", stdout);
    int n, m, s, d, x, y, c, z;
    scanf("%d%d%d%d",&n, &m, &s, &d);
    for (int i = 1; i <= m; ++i) {
        scanf("%d%d%d%d", &x, &y, &c, &z);
        mcmf.add_edge(x, y, c, z);
    }
    printf("%d",mcmf.flowCost(s, d));
    return 0;
}