Cod sursa(job #1501819)

Utilizator geniucosOncescu Costin geniucos Data 13 octombrie 2015 21:04:19
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.51 kb
#include<queue>
#include<cstdio>
#include<vector>

using namespace std;

int N, M;
int INF = 1 << 30;

class flow_network
{
public:

    int N, M, S, D;
    int X[240009], Y[240009], C[240009], F[240009], bani[240009], t[120009], in_q[120009], bell[120009];
    vector < int > v[120009];

    void add_edge (int a, int b, int cap, int ban)
    {
        X[++M] = a, Y[M] = b, C[M] = cap, bani[M] = ban, v[a].push_back (M);
        X[++M] = b, Y[M] = a, C[M] = 0, bani[M] = -ban, v[b].push_back (M);
    }

    int opus (int edge)
    {
        if (edge & 1) return edge + 1;
        return edge - 1;
    }

    bool bellman ()
    {
        queue < int > cc;
        for (int i=1; i<=N; i++)
            t[i] = -1, in_q[i] = 0, bell[i] = INF;
        cc.push (S), t[S] = 0, in_q[S] = 1, bell[S] = 0;
        while (!cc.empty ())
        {
            int nod = cc.front ();
            cc.pop ();
            in_q[nod] = 0;
            for (vector < int > :: iterator it = v[nod].begin (); it != v[nod].end (); it ++)
                if (F[*it] < C[*it] && bell[Y[*it]] > bell[nod] + bani[*it])
                {
                    bell[Y[*it]] = bell[nod] + bani[*it];
                    t[Y[*it]] = *it;
                    if (in_q[Y[*it]] == 0)
                    {
                        in_q[Y[*it]] = 1;
                        cc.push (Y[*it]);
                    }
                }
        }
        return (bell[D] != INF);
    }

    pair < int , int > Max_Flow ()
    {
        int flow = 0, cost = 0;
        while (bellman ())
        {
            int mini = INF;
            for (int i=D; i != S; i = X[t[i]])
                if (C[t[i]] - F[t[i]] < mini)
                    mini = C[t[i]] - F[t[i]];
            flow += mini, cost += mini * bell[D];
            for (int i=D; i != S; i = X[t[i]])
                F[t[i]] += mini, F[opus (t[i])] -= mini;
        }
        return make_pair (flow, cost);
    }

    void Clear ()
    {
        for (int i=1; i<=M; i++)
            X[i] = Y[i] = C[i] = F[i] = bani[i] = 0;
        for (int i=1; i<=N; i++)
            v[i].clear (), t[i] = in_q[i] = bell[i] = 0;
        M = 0;
    }
}net;

int main ()
{
freopen ("fmcm.in", "r", stdin);
freopen ("fmcm.out", "w", stdout);

scanf ("%d %d %d %d", &N, &M, &net.S, &net.D), net.N = N;
while (M --)
{
    int x, y, c, v;
    scanf ("%d %d %d %d", &x, &y, &c, &v);
    net.add_edge (x, y, c, v);
}
printf ("%d\n", (net.Max_Flow ()).second);

return 0;
}