Cod sursa(job #2255779)

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

#define mp   std::make_pair
#define inf  (int)(1e9)
#define MaxN 355
#define Dist first
#define Src  second

class InParser {
private:
    FILE *fin;
    char *buff;
    int sp;

    char read_ch() {
        ++sp;
        if (sp == 4096) {
            sp = 0;
            fread(buff, 1, 4096, fin);
        }
        return buff[sp];
    }

public:
    InParser(const char* nume) {
        fin = fopen(nume, "r");
        buff = new char[4096]();
        sp = 4095;
    }

    InParser& operator >> (int &n) {
        char c;
        while (!isdigit(c = read_ch()) && c != '-');
        int sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }

    InParser& operator >> (long long &n) {
        char c;
        n = 0;
        while (!isdigit(c = read_ch()) && c != '-');
        long long sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }
};

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

std::queue <int> Queue;
std::priority_queue <std::pair <int, int>, std::vector <std::pair <int, int>>, std::greater <std::pair <int, int>>> PQueue;
int M, S, D;

template <int NNodes>
class DirectedGraph {
public:
    int N;
    int MinCost;
    inline void AddEdge(int Src, int Dest, int Capacity, int Cost) {
        this->Capacity[Src][Dest] = Capacity;
        this->Cost[Src][Dest] = Cost;
        this->Cost[Dest][Src] = -Cost;
        Node[Src].ADC.push_back(Dest);
        Node[Dest].ADC.push_back(Src);
    }

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

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

        int Front;
        while(!Queue.empty()) {
            Front = Queue.front();
            Queue.pop();

            InQueue[Front] = 0;
            for (auto Vecin:Node[Front].ADC)
                if (Capacity[Front][Vecin] && BFDist[Vecin] > BFDist[Front] + Cost[Front][Vecin]) {
                    BFDist[Vecin] = BFDist[Front] + Cost[Front][Vecin];
                    if (!InQueue[Vecin])
                        InQueue[Vecin] = 1,
                        Queue.push(Vecin);
            }
        }
    }

    inline bool Dijkstra() {
        for (int i=0; i<N; ++i)
            Dist[i+1] = inf;
        Dist[S] = 0;
        PQueue.push(mp(0, S));

        std::pair <int, int> Top;
        while(!PQueue.empty()) {
            Top = PQueue.top();
            PQueue.pop();

            if (Dist[Top.Src] < Top.Dist) continue;

            for (auto Vecin:Node[Top.Src].ADC)
                if (Dist[Vecin] > Dist[Top.Src] + Cost[Top.Src][Vecin] + BFDist[Top.Src] - BFDist[Vecin] && Capacity[Top.Src][Vecin]) {
                    Dist[Vecin] = Dist[Top.Src] + Cost[Top.Src][Vecin] + BFDist[Top.Src] - BFDist[Vecin];
                    Parent[Vecin] = Top.Src;

                    PQueue.push(mp(Dist[Vecin], Vecin));
                 }
        }

        if(Dist[D] == inf) return false;
        int Min = inf, x = D;
        while(x != S)
            Min = std::min(Min, Capacity[Parent[x]][x]),
            x = Parent[x];
        if (Min <= 0) return true;

        x = D;
        MinCost += Min * (Dist[D] + BFDist[D]);
        while(x != S)
            Capacity[x][Parent[x]] += Min,
            Capacity[Parent[x]][x] -= Min,
            x = Parent[x];
        return true;
    }

private:
    bool InQueue[NNodes];
    int Capacity[NNodes][NNodes],
        Cost[NNodes][NNodes];
    int BFDist[NNodes], Dist[NNodes];
    int Parent[NNodes];

    struct GraphNode {
        std::list <int> ADC;
    }   Node[NNodes];

};  DirectedGraph <MaxN> Graph;

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

void Rezolvare() {
    Graph.BellmanFord();

    while(Graph.Dijkstra());
    OutFile << Graph.MinCost << '\n';
}

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

    return 0;
}