Cod sursa(job #867348)

Utilizator SpiderManSimoiu Robert SpiderMan Data 29 ianuarie 2013 16:51:56
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.49 kb
# include <algorithm>
# include <cassert>
# include <cstdio>
# include <cstring>
# include <vector>
# include <queue>
using namespace std;

# define x first
# define y second

typedef pair <int, int> PR;
const char *FIN = "fmcm.in", *FOU = "fmcm.out";
const int MAX = 355, oo = 0x3f3f3f3f;

vector <PR> G[MAX];
int C[MAX][MAX], F[MAX][MAX], dp[MAX], dpV[MAX], dpN[MAX], T[MAX], viz[MAX];
int N, M, S, D;
int cm;

priority_queue <PR, vector <PR>, greater <PR> > Q;

inline void getmin (int &a, int b) {
    a = a < b ? a : b;
}

void bellman (void) {
    queue <int> Q;
    memset (dpV, oo, sizeof (dpV));
    dpV[S] = 0, viz[S] = 1;
    for (Q.push (S); !Q.empty ();) {
        int X = Q.front(); viz[X] = 0; Q.pop ();
        for (vector <PR> :: iterator it = G[X].begin (); it != G[X].end (); ++it)
            if (dpV[X] + it -> y < dpV[it -> x] && C[X][it -> x] != F[X][it -> x]) {
                dpV[it -> x] = dpV[X] + it -> y;
                if (viz[it -> x] == 0)
                    viz[it -> x] = 1, Q.push (it -> x);
            }
    }
}

inline int dijkstra (void) {
    memset (dp, oo, sizeof (dp));
    dp[S] = dpN[S] = 0;
    for (Q.push (make_pair (0, S)); !Q.empty ();) {
        PR X = Q.top(); Q.pop ();
        int node = X.y, cost = X.x;
        if (dp[node] != cost) continue;
        for (vector <PR> :: iterator it = G[node].begin (); it != G[node].end (); ++it)
            if (dp[node] + it -> y + dpV[node] - dpV[it -> x] < dp[it -> x] && C[node][it -> x] != F[node][it -> x]) {
                dp[it -> x] = dp[node] + it -> y + dpV[node] - dpV[it -> x], T[it -> x] = node;
                dpN[it -> x] = dpN[node] + it -> y;
                Q.push (make_pair (dp[it -> x], it -> x));
            }
    }
    memcpy (dpV, dpN, sizeof (int) * (N + 1));
    return dp[D] != oo;
}

int main (void) {
    assert (freopen (FIN, "r", stdin));

    assert (scanf ("%d %d %d %d", &N, &M, &S, &D) == 4);
    for (int i = 1, x, y, z, c; i <= M; ++i) {
        assert (scanf ("%d %d %d %d", &x, &y, &c, &z) == 4), C[x][y] = c;
        G[x].push_back (make_pair (y, +z));
        G[y].push_back (make_pair (x, -z));
    }
    bellman ();
    for (int fmin = 0; dijkstra (); cm += fmin * dpN[D]) {
        fmin = oo;
        for (int i = D; i != S; i = T[i])
            getmin (fmin, C[T[i]][i] - F[T[i]][i]);
        for (int i = D; i != S; i = T[i])
            F[T[i]][i] += fmin, F[i][T[i]] -= fmin;
    }
    fprintf (fopen (FOU, "w"), "%d", cm);
}