Cod sursa(job #1882218)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 17 februarie 2017 00:26:09
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.4 kb
#include <bits/stdc++.h>
using namespace std;

const int NMAX = 351,
           INF = 2e9;

struct DJK {
    int nod, dst;

    inline bool operator < (const DJK &arg) const { // God forgive me
        return dst > arg.dst; } };

int n, m, s, d, rcost;
double time_pump, time_dijk;

vector<int> g[NMAX];
int dist[NMAX], ddist[NMAX], far[NMAX], cap[NMAX][NMAX], cst[NMAX][NMAX], flw[NMAX][NMAX];

void init() {
    deque<int> dq;
    bitset<NMAX> iq(0);
    int u;

    dq.push_back(s);
    memset(dist, 0x3f, sizeof dist);
    dist[s] = 0;

    while (!dq.empty()) {
        u = dq.front(), dq.pop_front();
        iq[u] = false;

        for (auto v: g[u]) if (dist[v] > dist[u] + cst[u][v] && cap[u][v] > 0 && !iq[v]) {
            dq.push_back(v);
            dist[v] = dist[u] + cst[u][v];
            iq[v] = true; } } }

bool dijkstra() {
    static priority_queue<DJK> pq;
    int u;

    memset(ddist, 0x3f, sizeof ddist);
    pq.push({s, 0});
    ddist[s] = 0;

    while (!pq.empty()) {
        u = pq.top().nod;
        pq.pop();
        for (auto v: g[u]) if (cst[u][v] + ddist[u] < ddist[v] && cap[u][v] - flw[u][v] > 0) {
            far[v] = u;
            ddist[v] = ddist[u] + cst[u][v];
            pq.push({v, ddist[u] + cst[u][v]}); } }

    memcpy(dist, ddist, sizeof ddist);

    return (ddist[d] != 0x3f3f3f3f); }

void pump() {
    int sflow, scost;

    double bpmp, bdjk = clock();

    while (dijkstra()) {
        time_dijk+= clock() - bdjk;

        bpmp = clock();
        sflow = INF;
        scost = 0;
        for (int nod = d; nod != s; nod = far[nod]) {
            sflow = min(sflow, cap[far[nod]][nod] - flw[far[nod]][nod]);
            scost+= cst[far[nod]][nod] + dist[nod] - dist[far[nod]]; }
        for (int nod = d; nod != s; nod = far[nod]) {
            flw[far[nod]][nod]+= sflow;
            flw[nod][far[nod]]-= sflow; }
        time_pump+= clock() - bpmp;

        bdjk = clock();
        rcost+= sflow * (scost - dist[d]); } }

int main() {
    ifstream fi("fmcm.in");
    ofstream fo("fmcm.out");
    int cp, cs, x, y;

    fi >> n >> m >> s >> d;
    for (int i = 0; i < m; ++i) {
        fi >> x >> y >> cp >> cs;

        cap[x][y] = cp;
        cst[x][y] = cs, cst[y][x] = -cs;

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

    init();
    pump();

    fo << rcost << '\n';
    cerr << time_dijk / CLOCKS_PER_SEC << '\n';
    cerr << time_pump / CLOCKS_PER_SEC << '\n';

    return 0; }