Cod sursa(job #1985513)

Utilizator Dddarius95Darius-Florentin Neatu Dddarius95 Data 28 mai 2017 00:45:11
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 4.13 kb
#include <iostream>
#include <cstdio>
#include <fstream>
#include <vector>
#include <bitset>
#include <cassert>
#include <queue>
#include <cstring>
#include <algorithm>
#define NMAX 355
#define oo (1 << 30)
using namespace std;

int n, m, source, sink;
vector<int> G[NMAX];

int old_d[NMAX];
queue<int> Q;
bitset<NMAX> inQ;

int d[NMAX], p[NMAX], real_d[NMAX];
// struct cmp {
//     bool operator()(const int &a, const int &b) {
//         return d[a] > d[b];
//     }
// };
// priority_queue<int, vector<int>, cmp> pq;

typedef pair<int, int> state;
priority_queue<state, vector<state>, greater<state> > pq;

int flow[NMAX][NMAX], cap[NMAX][NMAX], cost[NMAX][NMAX];

void read_input() {
    cin >> n >> m >> source >> sink;

    for (int i = 1; i <= m; ++i) {
        int x, y, c, z;
        cin >>  x >> y >> c >> z;

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

        cap[x][y] = c;

        cost[x][y] = +z;
        cost[y][z] = -z;
    }
}


int x, y, c, z;
#define pb push_back
#define f cin
void ceplm() {
    f >> n >> m >> source >> sink;
    for(int i = 1; i <= m; ++i) {
        f >> x >> y >> c >> z;

        G[x].pb(y);
        G[y].pb(x);

        cap[x][y]=c;

        cost[x][y] = +z;
        cost[y][x] = -z;
    }
}
int Bellman(int source) {
    for(int i = 1; i <= n; ++i) {
        old_d[i] = oo;
    }

    Q.push(source);
    old_d[source] = 0;
    inQ[source] = 1;

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

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

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

bool Dijkstra(int source, int sink) {
    // cout << "Start Dijkstra\n";
    for (int i = 1; i <= n; ++i) {
        p[i] = oo;
        d[i] = oo;
        real_d[i] = oo;
    }

    pq.push( state(0, source) );
    p[source] = 0;
    d[source] = 0;
    real_d[source] = 0;

    while (!pq.empty()) {
        state s = pq.top();
        pq.pop();

        int node = s.second;
        int dist = s.first;

        if (d[node] < dist) {
            continue;
        }

        for (auto it : G[node]) {
            long long d_aux = d[node] + cost[node][it] + old_d[node] - old_d[it];

            if (d_aux < 1LL * d[it] && flow[node][it] < cap[node][it]) {
                d[it] = d_aux;
                p[it] = node;
                real_d[it] = real_d[node] + cost[node][it];

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

    // for (int i = 1; i <= n; ++i) {
    //     old_d[i] = real_d[i];
    //     cout << real_d[i] << " ";
    // }
    // cout << '\n';

    // cout << d[sink] << " " << p[sink] <<  '\n';

    return d[sink] != oo;
}



void FMCM(int source, int sink) {
    int maxFlow = 0, minCost = 0;

    while (Dijkstra(source, sink)) {
        // for (auto it = G[sink].begin(); it != G[sink].end(); ++it) {
            // if (p[*it] != oo && flow[*it][sink] < cap[*it][sink]) {
                // p[sink] = *it;

        int minFlow = oo;
        for (int node = sink; node != source; node = p[node]) {
            int parent = p[node],
                available_flow = cap[ parent ][ node ] - flow[ parent ][ node ];

            minFlow = min(minFlow, available_flow);
        }

        if (minFlow > 0) {
            maxFlow += minFlow;
            minCost += minFlow * real_d[sink];

            for (int node = sink; node != source; node = p[node]) {
                int parent = p[node];
                flow[ parent ][ node ] += minFlow;
                flow[ node ][ parent ] -= minFlow;
            }
        }
            // }
        // }
    }

    cout << minCost << "\n";
    // cout << maxFlow << "\n";
}

int main() {
    assert( freopen("fmcm.in", "r", stdin) != NULL);
    assert( freopen("fmcm.out", "w", stdout) != NULL) ;

    // read_input();
    ceplm();
    Bellman(source);
    // for (int i = 1; i <= n; ++i) {
    //     cout << old_d[i] << ' ';
    // }
    // cout << "\n";
    FMCM(source, sink);

    return 0;
}