Cod sursa(job #2452339)

Utilizator Alex_BubBuburuzan Alexandru Alex_Bub Data 30 august 2019 15:18:47
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.37 kb
#include <fstream>
#include <vector>
#include <queue>
#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], oldC[NMax + 5][NMax + 5], TT[NMax + 5], Dist[NMax + 5], Sol;
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;;
            }
    }
    for(int i = 1; i <= N; i++)
        for(auto j : G[i])
            C[i][j] += Dist[i] - Dist[j];
}

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

    Dist[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 cost = Dist[Nod] + C[Nod][Vecin];

            if(D[Nod][Vecin] && cost < Dist[Vecin])
            {
                Dist[Vecin] = cost;
                Heap.push({cost, Vecin});
                TT[Vecin] = Nod;
            }
        }
    }
    return (Dist[B] != oo);
}

void Flux()
{
    Bellman();

    while(Dijkstra())
    {
        int mini = oo, cost = 0;

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

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

        Sol += mini * cost;
    }
    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;
        oldC[a][b] = z, oldC[b][a] = -z;
    }
    Flux();

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

    return 0;
}