Cod sursa(job #1156168)

Utilizator florin.elfusFlorin Elfus florin.elfus Data 27 martie 2014 14:41:38
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
#include <stdio.h>
#include <vector>
#include <queue>

using namespace std;

int cap[351][351], flow[351][351], cost[351][351];
vector <int> G[351];

int N, M, S, D;

int maxFlow = 0, minCost = 0;
int dist[351], father[351];
queue <int> q;
bool inQ[351];

bool BellmanFord() {
    for (int i = 1; i <= N; ++i)
        dist[i] = 1 << 29;
    q.push(S); inQ[S] = 1;
    dist[S] = 0;

    while (!q.empty()) {
        int nod = q.front();
        vector <int> :: iterator it;

        for (it = G[nod].begin(); it != G[nod].end(); ++it)
            if (flow[nod][*it] < cap[nod][*it])
                if (dist[nod] + cost[nod][*it] < dist[*it]) {
                    dist[*it] = dist[nod] + cost[nod][*it];
                    father[*it] = nod;
                    if (!inQ[*it]) {
                        inQ[*it] = 1;
                        q.push(*it);
                    }
                }

        q.pop(); inQ[nod] = 0;
    }

    return dist[D] != (1 << 29);
}

void augment() {
    int fmin = 1 << 30;
    for (int nod = D; nod != S; nod = father[nod])
        if (cap[father[nod]][nod] - flow[father[nod]][nod] < fmin)
            fmin = cap[father[nod]][nod] - flow[father[nod]][nod];

    for (int nod = D; nod != S; nod = father[nod]) {
        flow[father[nod]][nod] += fmin;
        flow[nod][father[nod]] -= fmin;
    }

    maxFlow += fmin;
    minCost += fmin * dist[D];
}

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

    scanf("%d%d%d%d", &N, &M, &S, &D);
    for (int i = 1; i <= M; ++i) {
        int xx, yy, _cap, _cost;
        scanf("%d%d%d%d", &xx, &yy, &_cap, &_cost);
        G[xx].push_back(yy);
        cap[xx][yy] = _cap;
        cost[xx][yy] = _cost;
        cost[yy][xx] = -_cost;
    }

    while (BellmanFord())
        augment();

    printf("%d", minCost);
    return 0;
}