Cod sursa(job #2247644)

Utilizator Menage_a_011UPB Cheseli Neatu Popescu Menage_a_011 Data 28 septembrie 2018 21:20:14
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.77 kb
#include <bits/stdc++.h>
using namespace std;

#define NMAX 355
#define kInf (1 << 30)

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
#define cin fin
#define cout fout


int n, m, S, D, p[NMAX], d[NMAX];
int cost[NMAX][NMAX], cap[NMAX][NMAX], flow[NMAX][NMAX],  real_d[NMAX], h[NMAX];
vector<int> G[NMAX];

void read_input() {
    cin >> n >> m >> S >> D;
    for (int i = 1; i <= m; ++i) {
        int x, y, c, z;
        cin >> x >> y >> c >> z;

        cap[x][y] = c;
        cost[x][y] = z;
        cost[y][x] = -z;

        G[x].push_back(y);
        G[y].push_back(x);
    }
}


void Bellman(int S, int h[NMAX]) {
    for (int i = 1; i <= n; ++i) {
        h[i] = kInf;
    }

    queue<int> q;
    bitset<NMAX> inQ;
    q.push(S);
    h[S] = 0;
    inQ[S] = 1;

    while (!q.empty()) {
        auto node = q.front();
        q.pop();
        inQ[node] = 0;

        for (auto it : G[node]) {
            if (h[node] + cost[node][it] < h[node] && flow[node][it] < cap[node][it]) {
                h[it] = h[node] + cost[node][it];

                if (!inQ[it]) {
                    inQ[it] = 1;
                    q.push(it);
                }
            }
        }

    }
}

int Dijkstra(int S, int D) {
    for (int i = 1; i <= n; ++i) {
        d[i] = kInf;
        real_d[i] = kInf;
        p[i] = kInf;
    }

    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    pq.push({0, S});
    d[S] = 0;
    real_d[S] = 0;
    p[S] = 0;

    while (!pq.empty()) {
        auto tmp = pq.top();
        pq.pop();

        auto dist = tmp.first;
        auto node = tmp.second;
        if (d[node] < dist) {
            continue;
        }

        for (auto it : G[node]) {
            long long d_aux = 1LL * d[node] +  cost[node][it] + h[node] - h[it];
            if (d_aux < 1LL * d[it] && flow[node][it] < cap[node][it]) {
                d[it] = d_aux;
                real_d[it] = real_d[node] + cost[node][it];
                p[it] = node;

                pq.push({d[it], it});
            }
        }
    }

    for (int i = 1; i <= n; ++i) {
        h[i] = real_d[i];
    }

    return d[D] != kInf;
}

void get_fmcm() {
    int maxFlow = 0, flowCost = 0;

    Bellman(S, h);
    while (Dijkstra(S, D)) {
        int minFlow = kInf;
        for (auto node = D; node != S; node = p[node]) {
            minFlow = min(minFlow, cap[p[node]][node] - flow[p[node]][node]);
        }

        if (minFlow > 0) {
            maxFlow += minFlow;
            flowCost += minFlow * real_d[D];

            for (auto node = D; node != S; node = p[node]) {
                flow[p[node]][node] += minFlow;
                flow[node][p[node]] -= minFlow;
            }
        }
    }

    cout << flowCost << "\n";
}


int main() {
    read_input();
    get_fmcm();
    return 0;
}