Cod sursa(job #1414161)

Utilizator retrogradLucian Bicsi retrograd Data 2 aprilie 2015 13:30:45
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.63 kb
#include<fstream>
#include<vector>
#include<queue>
#include<cstring>

using namespace std;
typedef int var;

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

#define MAXN 700

var S, D;
var n;
var F[MAXN][MAXN], C[MAXN][MAXN], K[MAXN][MAXN];
var OLDD[MAXN], REALD[MAXN], DIST[MAXN];
var PARENT[MAXN];

vector<var> G[MAXN];
void addEdge(var a, var b, var cap, var cost) {
    G[a].push_back(b);
    G[b].push_back(a);
    C[a][b] = cap;
    K[a][b] = cost;
    K[b][a] = -cost;
}

bool INQ[MAXN];
void Bellman() {
    queue<var> Q;

    memset(OLDD, 0xf, sizeof(OLDD));
    OLDD[S] = 0;

    Q.push(S);
    while(!Q.empty()) {
        var node = Q.front();
        Q.pop();
        INQ[node] = 0;

        for(auto vec : G[node]) {
            if(OLDD[vec] > OLDD[node] + K[node][vec] && F[node][vec] < C[node][vec]) {
                OLDD[vec] = OLDD[node] + K[node][vec];
                if(!INQ[vec]) {
                    Q.push(vec);
                    INQ[vec] = 1;
                }
            }
        }
    }
}
typedef pair<var, var> pii;
#define mp make_pair
priority_queue< pii, vector<pii> >Q;

bool Dijkstra() {
    memset(DIST, 0xf, sizeof(DIST));
    memset(REALD, 0xf, sizeof(REALD));
    memset(PARENT, 0, sizeof(PARENT));

    DIST[S] = REALD[S] = 0;
    Q.push(mp(0, S));

    while(!Q.empty()) {
        auto top = Q.top();
        Q.pop();
        var node = top.second;

        if(-top.first > DIST[node])
            continue;

        for(auto vec : G[node]) {
            if(F[node][vec] < C[node][vec] && DIST[vec] > DIST[node] + OLDD[node] - OLDD[vec] + K[node][vec]) {
                DIST[vec] = DIST[node] + OLDD[node] - OLDD[vec] + K[node][vec];
                PARENT[vec] = node;
                REALD[vec] = REALD[node] + K[node][vec];

                Q.push(mp(-DIST[vec], vec));
            }
        }
    }

    return PARENT[D] != 0;
}


var fmcm() {

    var total = 0;
    Bellman();

    while(Dijkstra()) {
        var M = (1 << 30);
        for(var node = D; node != S; node = PARENT[node]) {
            M = min(M, C[PARENT[node]][node] - F[PARENT[node]][node]);
        }
        for(var node = D; node != S; node = PARENT[node]) {
            F[PARENT[node]][node] += M;
            F[node][PARENT[node]] -= M;

            total += K[PARENT[node]][node] * M;
        }

        memcpy(OLDD, REALD, sizeof(OLDD));
    }

    return total;
}


int main() {
    var m, a, b, c, d;
    fin>>n>>m>>S>>D;

    while(m--) {
        fin>>a>>b>>c>>d;
        addEdge(a, b, c, d);
    }

    fout<<fmcm();
    return 0;
}