Cod sursa(job #1484837)

Utilizator geniucosOncescu Costin geniucos Data 12 septembrie 2015 00:03:14
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.79 kb
#include<cstdio>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<map>
#include<set>
#include<queue>
#include<bitset>
#include<algorithm>

using namespace std;

class MaxFlowMinCost
{
    public:
    int N, M, S, D, ap[7009], t[7009], bell[7009], in_q[7009];
    int F[60009], C[60009], bani[60009], X[60009], Y[60009];
    vector < int > v[60009];

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

    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, bell[i] = 1<<30, in_q[i] = 0;
        t[S] = 0, in_q[S] = 1, bell[S] = 0;
        cc.push (S);
        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 (bell[Y[*it]] > bell[nod] + bani[*it] && C[*it] > F[*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] < (1<<30));
    }

    int compute_flow ()
    {
        int cost = 0, tot_fl = 0;
        while (bellman ())
        {
            int mini = 1<<30;
            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]];
            cost += mini * bell[D];
            tot_fl += mini;
            for (int i=D; i != S; i = X[t[i]])
            {
                F[t[i]] += mini;
                F[opus (t[i])] -= mini;
            }
        }
        //printf ("fluxu e %d\n", tot_fl);
        return cost;
    }

    void print ()
    {
        for (int i=1; i<=N; i++)
            for (vector < int > :: iterator it = v[i].begin (); it != v[i].end (); it ++)
                if (F[*it] > 0) printf ("%d -> %d capac %d  /  %d\n", X[*it], Y[*it], F[*it], C[*it]);
    }
}flow_network;

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

int M;
scanf ("%d %d %d %d", &flow_network.N, &M, &flow_network.S, &flow_network.D);
while (M)
{
    M --;
    int x, y, c, b;
    scanf ("%d %d %d %d", &x, &y, &c, &b);
    flow_network.add_edge (x, y, c, b);
}
printf ("%d\n", flow_network.compute_flow ());

return 0;
}