Cod sursa(job #1138232)

Utilizator FlameingoAiordachioaei Marius Flameingo Data 9 martie 2014 19:41:58
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.6 kb
#include <cstdio>
#include <bitset>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

const int NMAX = 353, INFI = 2e9;

vector <short> G[NMAX];
queue <short> Q;
int dist[NMAX], _dist[NMAX], __dist[NMAX], ans;
short N, source, sink, cap[NMAX][NMAX], flow[NMAX][NMAX], cost[NMAX][NMAX], T[NMAX];

struct predicate {

    inline bool operator () (const short &a, const short &b) {

        return _dist[a] > _dist[b];

    }

};

priority_queue <short, vector <short>, predicate> _Q;

inline void bellman_ford () {

    vector <short> :: iterator i;
    short node;
    for (node = 1; node <= N; ++node)
        dist[node] = INFI;
    dist[source] = 0;
    for (Q.push (source); !Q.empty (); Q.pop ()) {
        node = Q.front ();
        for (i = G[node].begin (); i != G[node].end (); ++i)
            if (cap[node][*i] && dist[*i] > dist[node] + cost[node][*i]) {
                dist[*i] = dist[node] + cost[node][*i];
                Q.push (*i);
            }
    }

}

inline bool dijkstra () {

    vector <short> :: iterator i;
    int t;
    short node, _min = 32000;
    for (node = 1; node <= N; ++node)
        _dist[node] = INFI;
    _dist[source] = 0;
    _Q.push (source);
    while (!_Q.empty ()) {
        node = _Q.top ();
        _Q.pop ();
        if (node == sink)
            continue;
        for (i = G[node].begin (); i != G[node].end (); ++i)
            if (flow[node][*i] < cap[node][*i] && _dist[*i] > (t = _dist[node] + cost[node][*i] + dist[node] - dist[*i])) {
                _dist[*i] = t;
                __dist[*i] = __dist[node] + cost[node][*i];
                T[*i] = node;
                _Q.push (*i);
            }
    }
    if (_dist[sink] == INFI)
        return 0;
    for (node = 1; node <= N; ++node)
        dist[node] = __dist[node];
    for (node = sink; node != source; node = T[node])
        _min = min ((int)_min, cap[T[node]][node] - flow[T[node]][node]);
    for (node = sink; node != source; node = T[node]) {
        flow[T[node]][node] += _min;
        flow[node][T[node]] -= _min;
    }
    ans += _min * __dist[sink];
    return 1;

}

int main () {

    freopen ("fmcm.in", "r", stdin);
    freopen ("fmcm.out", "w", stdout);
    short M, a, b, c, z;
    scanf ("%hd%hd%hd%hd", &N, &M, &source, &sink);
    while (M--) {
        scanf ("%hd%hd%hd%hd", &a, &b, &c, &z);
        G[a].push_back (b);
        G[b].push_back (a);
        cap[a][b] = c;
        cost[a][b] = z;
        cost[b][a] = -z;
    }
    bellman_ford ();
    while (dijkstra ());
    printf ("%d", ans);

}