Cod sursa(job #1957302)

Utilizator razvandRazvan Dumitru razvand Data 7 aprilie 2017 14:32:25
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.24 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <climits>

using namespace std;

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

int n,m,s,d;
int flow[353][12503];
int cost[353][12503];
int newC[353][12503];
int magicC[353];
vector<int> e[353];
int cmin[353];
int bef[353];
bool viz[353];

bool dijkstra(int nod) {

    for(int i = 1; i <= n; i++) {
        cmin[i] = INT_MAX/2;
        bef[i] = 0;
        viz[i] = false;
    }
    cmin[nod] = 0;

    priority_queue<pair<int, int>> Q;
    Q.push({0, nod});
    int c;
    int nx;

    while(!Q.empty()) {

        c = -Q.top().first;
        nod = Q.top().second;
        Q.pop();

        if(viz[nod])
            continue;
        viz[nod] = 1;
        //cout << "TEST " << nod << '\n';

        for(int i = 0; i < e[nod].size(); i++) {

            nx = e[nod][i];

            if(flow[nod][nx] == 0)
                continue;
            if(viz[nx])
                continue;

            if(cmin[nx] > cmin[nod]+newC[nod][nx]) {

                cmin[nx] = cmin[nod]+newC[nod][nx];
                Q.push({-cmin[nx], nx});
                bef[nx] = nod;

            }

        }

    }

    if(cmin[d] != INT_MAX/2)
        return 1;
    return 0;

}

bool bellman() {

    queue<pair<int, int>> Q;

    for(int i = 1; i <= n; i++) {
        Q.push({i, 0});
        magicC[i] = 0;
    }

    int c;
    int nx;
    int nod;

    while(!Q.empty()) {

        nod = Q.front().first;
        c = Q.front().second;
        Q.pop();

        if(c != magicC[nod])
            continue;

        for(int i = 0; i < e[nod].size(); i++) {

            nx = e[nod][i];

            if(flow[nod][nx] == 0)
                continue;

            if(magicC[nx] > magicC[nod]+cost[nod][nx]) {

                magicC[nx] = magicC[nod]+cost[nod][nx];
                Q.push({nx, magicC[nx]});

            }

        }

    }

    for(int i = 1; i <= n; i++) {
        for(int j = 0; j < e[i].size(); j++) {
            nx = e[i][j];
            newC[i][nx] = magicC[i] - magicC[nx] + cost[i][nx];
            //cout << i << " " << nx << " " << newC[i][nx] << " " << magicC[i] << " " << cmin[nx] << '\n';
        }
    }

    if(magicC[d] != INT_MAX/2)
        return 1;
    return 0;

}

int main() {

    in >> n >> m >> s >> d;
    int x,y,z,w;

    for(int i = 1; i <= m; i++) {
        in >> x >> y >> z >> w;

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

        flow[x][y] = z;
        cost[x][y] = w;
        cost[y][x] = -w;

    }

    int flmx = 0;
    int cosM = 0;
    bellman();

    while(dijkstra(s)) {

        int flmin = INT_MAX;
        int crr = d;

        while(crr != s) {
            flmin = min(flmin, flow[bef[crr]][crr]);
            crr = bef[crr];
        }

        crr = d;
        flmx += flmin;
        cmin[d] = cmin[d] - magicC[s] + magicC[d];
        cosM += flmin*cmin[d];

        while(crr != s) {
            flow[bef[crr]][crr] -= flmin;
            flow[crr][bef[crr]] += flmin;
            crr = bef[crr];
        }

        //cout << "TEST " << flmx << " " << cosM << '\n';

    }

    out << cosM << '\n';

    return 0;
}