Cod sursa(job #1190459)

Utilizator andreiiiiPopa Andrei andreiiii Data 25 mai 2014 13:27:49
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>

using namespace std;

const int Nmax = 355, INF = 0x3f3f3f3f;

vector<int> G[Nmax];

int C[Nmax][Nmax], F[Nmax][Nmax];
int Cost[Nmax][Nmax];
int OldC[Nmax], RealC[Nmax], Cst[Nmax];
int From[Nmax];
int N, S, D, Flow, FlowC;

bitset <Nmax> inQueue;

void BellmanFord()
{
    memset(OldC, INF, sizeof(OldC));
    OldC[S] = 0;

    queue<int> Q;
    inQueue.reset();

    for (Q.push(S); !Q.empty(); Q.pop())
    {
        int node = Q.front();
        inQueue[node] = 0;

        for (auto p: G[node])
        {
            if (C[node][p] == F[node][p]) continue;

            if (OldC[p] > OldC[node] + Cost[node][p])
            {
                OldC[p] = OldC[node] + Cost[node][p];

                if (!inQueue[p])
                {
                    Q.push(p);
                    inQueue[p] = 1;
                }
            }
        }
    }
}

struct comp {
    bool operator()(const pair<int, int> &a, const pair<int, int> &b)
    {
        return a > b;
    }
};

bool Dijkstra()
{
    memset(Cst, INF, sizeof(Cst));
    Cst[S] = 0;

    priority_queue<pair<int, int>, vector<pair<int, int>>, comp> H;

    for (H.push(make_pair(0, S)); !H.empty();)
    {
        int node = H.top().second, c = H.top().first;
        H.pop();

        if (Cst[node] != c) continue;

        for (auto p: G[node])
        {
            if (C[node][p] == F[node][p]) continue;
            int cst = Cst[node] + Cost[node][p] + OldC[node] - OldC[p];

            if (cst < Cst[p])
            {
                Cst[p] = cst;
                RealC[p] = RealC[node] + Cost[node][p];

                From[p] = node;

                H.push(make_pair(Cst[p], p));
            }
        }
    }

    memcpy(OldC, RealC, sizeof(OldC));

    if (Cst[D] == INF) return 0;

    int fmin = INF;

    for (int i = D; i != S; i = From[i])
        fmin = min(fmin, C[From[i]][i] - F[From[i]][i]);

    Flow += fmin;
    FlowC += fmin * RealC[D];

    for (int i = D; i != S; i = From[i])
    {
        F[From[i]][i] += fmin;
        F[i][From[i]] -= fmin;
    }

    return 1;
}

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

    int M;
    scanf("%d%d%d%d", &N, &M, &S, &D);

    while (M--)
    {
        int x, y, i, j;
        scanf("%d%d%d%d", &x, &y, &i, &j);

        G[x].push_back(y);
        G[y].push_back(x);

        C[x][y] = i;
        Cost[x][y] = j;
        Cost[y][x] = -j;
    }

    BellmanFord();
    while(Dijkstra());

    printf("%d\n", FlowC);
}