Cod sursa(job #2452359)

Utilizator Alex_BubBuburuzan Alexandru Alex_Bub Data 30 august 2019 15:36:42
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.41 kb
#include <fstream>
#include <vector>
#include <queue>
#include <iostream>
#define pp pair<int, int>

using namespace std;

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");

const int NMax = 350, oo = 1e9;

vector <int> G[NMax + 5];
int N, M, A, B, C[NMax + 5][NMax + 5], D[NMax + 5][NMax + 5], TT[NMax + 5], Dist[NMax + 5], Sol, RealDist[NMax + 5], DP[NMax + 5];
bool Use[NMax + 5];

queue <int> Q;
priority_queue <pp, vector<pp>, greater<pp> > Heap;

void Bellman()
{
    for(int i = 1; i <= N; i++)
        Dist[i] = oo;

    Dist[A] = 0, Q.push(A); Use[A] = 1;

    while(!Q.empty())
    {
        int Nod = Q.front(); Q.pop();
        Use[Nod] = 0;

        for(auto Vecin : G[Nod])
            if(Dist[Nod] + C[Nod][Vecin] < Dist[Vecin] && D[Nod][Vecin])
            {
                Dist[Vecin] = Dist[Nod] + C[Nod][Vecin];

                if(Use[Vecin] == 0)
                    Q.push(Vecin), Use[Vecin] = 1;;
            }
    }
}

bool Dijkstra()
{
    for(int i = 1; i <= N; i++)
        DP[i] = oo, Use[i] = 0, TT[i] = 0;

    DP[A] = RealDist[A] = 0;
    Heap.push({0, A});

    while(!Heap.empty())
    {
        int Nod = Heap.top().second;
        Heap.pop();

        if(Use[Nod]) continue;

        for(auto Vecin : G[Nod])
        {
            int edge = C[Nod][Vecin] + Dist[Nod] - Dist[Vecin];

            if(D[Nod][Vecin] && DP[Nod] + edge < DP[Vecin])
            {
                DP[Vecin] = DP[Nod] + edge;
                Heap.push({DP[Vecin], Vecin});
                TT[Vecin] = Nod;
                RealDist[Vecin] = RealDist[Nod] + C[Nod][Vecin];
            }
        }
    }
    return (DP[B] != oo);
}

void Flux()
{
    Bellman();

    while(Dijkstra())
    {
        int mini = oo;

        for(int i = B; TT[i]; i = TT[i])
            mini = min(mini, D[TT[i]][i]);

        for(int i = B; TT[i]; i = TT[i])
            D[TT[i]][i] -= mini, D[i][TT[i]] += mini;

        Sol += mini * RealDist[B];

        for(int i = 1; i <= N; i++)
            Dist[i] = RealDist[i];
    }
    fout << Sol << '\n';
}

int main()
{
    fin >> N >> M >> A >> B;

    for(int i = 1, a, b, c, z; i <= M; i++)
    {
        fin >> a >> b >> c >> z;

        G[a].push_back({b});
        G[b].push_back({a});

        C[a][b] = z, C[b][a] = -z, D[a][b] = c;
    }
    Flux();

    fin.close();
    fout.close();

    return 0;
}