Cod sursa(job #1337119)

Utilizator retrogradLucian Bicsi retrograd Data 8 februarie 2015 16:50:16
Problema Flux maxim de cost minim Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.13 kb
#include<fstream>
#include<vector>
#include<queue>

using namespace std;
typedef int var;

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

const var MAXN = 351;
const var INF = 1000001;

var H[MAXN], POS[MAXN],
    COST[MAXN], PARENT[MAXN], DIST[MAXN],
    K[MAXN][MAXN], C[MAXN][MAXN], F[MAXN][MAXN];

vector<var> G[MAXN];

bool INQ[MAXN];

var n, heapsize, src, dest;

void swapp(var n1, var n2) {
    swap(H[n1], H[n2]);
    swap(POS[H[n1]], POS[H[n2]]);
}

void heap_up(var node) {
    if(node > 1 && COST[H[node/2]] > COST[H[node]]) {
        swapp(node, node/2);
        heap_up(node/2);
    }
}

void heap_down(var node) {
    if(node*2 > heapsize) return;
    var next = node*2;

    if(next+1 <= heapsize && COST[H[next+1]] < COST[H[next]]) {
        next++;
    }

    if(COST[H[node]] > COST[H[next]]) {
        swapp(node, next);
        heap_down(next);
    }
}

var extract_min() {
    var MIN = H[1];
    swapp(1, heapsize --);
    heap_down(1);
    return MIN;
}

bool dijkstra(var src, var dest) {
    for(var i=1; i<=n; i++) {
        H[i] = i;
        COST[i] = INF;
        PARENT[i] = 0;
        POS[i] = i;
    }

    COST[src] = 0;
    swapp(1, src);
    heapsize = n;


    while(heapsize) {
        var node = extract_min();
        for(vector<var>::iterator it = G[node].begin(); it != G[node].end(); ++it) {
            var vec = *it;
            if(COST[vec] > COST[node] + K[node][vec] + DIST[node] - DIST[vec] && F[node][vec] < C[node][vec]) {
                COST[vec] = COST[node] + K[node][vec] + DIST[node] - DIST[vec];
                PARENT[vec] = node;

                heap_up(vec);
            }
        }
    }

    return PARENT[dest] != 0;
}

void bellman(var src) {

    queue<var> Q;

    for(var i=1; i<=n; i++) {
        DIST[i] = INF;
        INQ[i] = 0;
    }

    DIST[src] = 0;
    Q.push(src);
    while(!Q.empty()) {
        var node = Q.front();
        Q.pop();
        INQ[node] = 0;
        for(vector<var>::iterator it = G[node].begin(); it != G[node].end(); ++it) {
            var vec = *it;
            if(DIST[vec] > DIST[node] + K[node][vec] && F[node][vec] < C[node][vec]) {
                DIST[vec] = DIST[node] + K[node][vec];

                if(!INQ[vec]) {
                    INQ[vec] = 1;
                    Q.push(vec);
                }
            }
        }
    }
}

var mfmc() {

    var total = 0;


   while(dijkstra(src, dest)) {
        var MIN = INF;

        for(var t=dest; t != src; t = PARENT[t]) {
            MIN = min(MIN, C[PARENT[t]][t] - F[PARENT[t]][t]);
        }

        for(var t=dest; t != src; t = PARENT[t]) {
            F[PARENT[t]][t] += MIN;
            F[t][PARENT[t]] -= MIN;
            total += (K[PARENT[t]][t]) * MIN;
        }
   }

   return total;
}

int main() {

    var m, a, b, c, k;
    fin>>n>>m>>src>>dest;
    while(m--) {
        fin>>a>>b>>c>>k;
        G[a].push_back(b);
        G[b].push_back(a);
        C[a][b] = c;
        K[a][b] = k;
        K[b][a] = -k;
    }

    bellman(src);
    fout<<mfmc();

    return 0;
}