Cod sursa(job #2255817)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 7 octombrie 2018 17:01:35
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.17 kb
#include <bits/stdc++.h>

#define MaxN 355
#define inf  (1<<30)

std::ifstream InFile("fmcm.in");
std::ofstream OutFile("fmcm.out");

int N, M, S, D;
int FlowCost;
int Parent[MaxN], BFDist[MaxN];
int Dist[MaxN], Real_Dist[MaxN];
int Cost[MaxN][MaxN],
    Capacity[MaxN][MaxN],
    Flow[MaxN][MaxN];

std::vector <int> G[MaxN];

std::priority_queue <std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<std::pair<int, int>>> PQueue;
std::queue <int> Queue;
bool InQueue[MaxN];

inline void AddEdge(int x, int y, int c, int z) {
    Capacity[x][y] = c;
    Cost[x][y] = z;
    Cost[y][x] = -z;

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

void BellmanFord() {
    for (int i=0; i<N; ++i)
        BFDist[i] = inf;

    Queue.push(S);
    BFDist[S] = 0;
    InQueue[S] = 1;

    int Front;
    while (!Queue.empty()) {
        Front = Queue.front();
        Queue.pop();
        InQueue[Front] = 0;

        for (auto Vecin:G[Front]) {
            if (BFDist[Front] + Cost[Front][Vecin] < BFDist[Front] && Flow[Front][Vecin] < Capacity[Front][Vecin]) {
                BFDist[Vecin] = BFDist[Front] + Cost[Front][Vecin];
                if (!InQueue[Vecin]) {
                    InQueue[Vecin] = 1;
                    Queue.push(Vecin);
                }
            }
        }
    }
}

int Dijkstra() {
    for (int i = 1; i <= N; ++i) {
        Dist[i] = inf;
        Real_Dist[i] = inf;
        Parent[i] = inf;
    }

    PQueue.push({0, S});
    Dist[S] = 0;
    Real_Dist[S] = 0;
    Parent[S] = 0;

    while (!PQueue.empty()) {
        auto tmp = PQueue.top();
        PQueue.pop();

        auto dist = tmp.first;
        auto node = tmp.second;
        if (Dist[node] < dist) {
            continue;
        }

        for (auto it : G[node]) {
            long long d_aux = 1LL * Dist[node] +  Cost[node][it] + BFDist[node] - BFDist[it];
            if (d_aux < 1LL * Dist[it] && Flow[node][it] < Capacity[node][it]) {
                Dist[it] = d_aux;
                Real_Dist[it] = Real_Dist[node] + Cost[node][it];
                Parent[it] = node;

                PQueue.push({Dist[it], it});
            }
        }
    }

    for (int i = 1; i <= N; ++i) {
        BFDist[i] = Real_Dist[i];
    }
    if(Dist[D] == inf) return false;

        int minFlow = inf;
        for (auto node = D; node != S; node = Parent[node]) {
            minFlow = std::min(minFlow, Capacity[Parent[node]][node] - Flow[Parent[node]][node]);
        }

        if (minFlow > 0) {
            FlowCost += minFlow * Real_Dist[D];

            for (auto node = D; node != S; node = Parent[node]) {
                Flow[Parent[node]][node] += minFlow;
                Flow[node][Parent[node]] -= minFlow;
            }
        }

    return true;
    return Dist[D] != inf;
}

void Rezolvare() {
    BellmanFord();
    while (Dijkstra());

    OutFile << FlowCost << "\n";
}

void Citire() {
    InFile >> N >> M >> S >> D;
    for (int i=0, x, y, c, z; i<M; ++i) {
        InFile >> x >> y >> c >> z;
        AddEdge(x, y, c, z);
    }
}

int main() {
    Citire();
    Rezolvare();

    return 0;
}