Cod sursa(job #1946931)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 30 martie 2017 16:43:33
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fi("fmcm.in");
ofstream fo("fmcm.out");

const int NMAX = 355,
           INF = 0x3f3f3f3f;

int n, m, s, d, ant;

vector<int> g[NMAX];
int cap[NMAX][NMAX],
    cst[NMAX][NMAX],
    dst[NMAX],
    ddv[NMAX],
    aux[NMAX],
    far[NMAX];

void bellman() {
    bitset<NMAX> inq;
    deque<int> dq;
    int u;

    memset(dst, 0x3f, sizeof dst);
    inq.reset();

    dst[s] = 0;
    inq[s] = true;
    dq.push_back(s);

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

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

bool dijkstra() {
    priority_queue<pair<int, int>> pq;
    int u, c;

    memset(ddv, 0x3f, sizeof ddv);
    memset(aux, 0x3f, sizeof aux);

    pq.emplace(0, s);
    aux[s] = ddv[s] = 0;

    while (!pq.empty()) {
        u = pq.top().second;
        c =-pq.top().first;
        pq.pop();

        if (c != aux[u])
            continue;

        for (auto v: g[u]) if (cap[u][v] != 0 && aux[u] + cst[u][v] + dst[u] - dst[v] < aux[v]) {
            far[v] = u;
            ddv[v] = ddv[u] + cst[u][v];
            aux[v] = aux[u] + cst[u][v] + dst[u] - dst[v];
            pq.emplace(-aux[v], v); } }

    memcpy(dst, ddv, sizeof dst);

    return (dst[d] != INF); }

int main() {
    int a, b;

    fi >> n >> m >> s >> d;
    for (int i = 0; i < m; ++i) {
        fi >> a >> b; fi >> cap[a][b] >> cst[a][b];
        cst[b][a] = -cst[a][b];
        g[a].push_back(b);
        g[b].push_back(a); }

    bellman();
    while (dijkstra()) {
        int flw = INF;

        for (int u = d; u != s; u = far[u])
            flw = min(flw, cap[far[u]][u]);

        ant+= flw * dst[d];
        for (int u = d; u != s; u = far[u]) {
            cap[far[u]][u]-= flw;
            cap[u][far[u]]+= flw; } }

    cerr << ant << '\n';
    fo << ant << '\n';

    return 0; }