Cod sursa(job #1577843)

Utilizator geniucosOncescu Costin geniucos Data 23 ianuarie 2016 22:00:08
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.4 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 C[409][409], f[409][409], bani[409][409], t[409], in_q[409], bell[409];
    vector < int > v[409];

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

    bool bellman()
    {
        queue < int > cc;
        for (int i=1; i<=N; i++)
            bell[i] = INF, in_q[i] = 0;
        bell[S] = 0;
        cc.push(S);
        in_q[S] = 1;
        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[nod][*it] < C[nod][*it] && bell[*it] > bell[nod] + bani[nod][*it])
                {
                    bell[*it] = bell[nod] + bani[nod][*it];
                    t[*it] = nod;
                    if (in_q[*it] == 0)
                    {
                        cc.push(*it);
                        in_q[*it] = 1;
                    }
                }
        }
        return (bell[D] != INF);
    }

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

    void Clear ()
    {
        for (int i=1; i<=N; i++)
            for (int j=1; j<=N; j++)
                f[i][j] = C[i][j] = bani[i][j] = 0;
        for (int i=1; i<=N; i++)
            v[i].clear (), t[i] = in_q[i] = bell[i] = 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;
}