Cod sursa(job #2962623)

Utilizator lucianul31Moisii Lucian lucianul31 Data 8 ianuarie 2023 21:16:19
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.96 kb
#include <iostream>
#include <fstream>
#include <string.h>
#include <vector>
#include <queue>

using namespace std;

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

const int NMAX = 356, INF = 2e9;
int N, M, TotalFlow, Source, Destination, Cost[NMAX][NMAX], Graph[NMAX][NMAX], Father[NMAX], inQueue[NMAX], BellmanFordDistance[NMAX], DijkstraDistance[NMAX], Distance[NMAX];
queue < int > q;
priority_queue < pair < int, int > > Q;
vector < int > Edges[NMAX];

void SetVector(int a[], int value)
{
    for(int i = 1; i <= N; i++)
        a[i] = value;
}

void BellmanFord()
{
    int X;
    SetVector(BellmanFordDistance, INF);
    BellmanFordDistance[Source] = 0;
    q.push(Source);
    inQueue[Source] = 1;
    while(!q.empty())
    {
        X = q.front();
        q.pop();
        inQueue[X] = 0;
        for(int &it : Edges[X])
            if(Graph[X][it] && BellmanFordDistance[X] + Cost[X][it] < BellmanFordDistance[it])
            {
                BellmanFordDistance[it] = BellmanFordDistance[X] + Cost[X][it];
                if(!inQueue[it])
                    inQueue[it] = 1, q.push(it);
            }
    }
}

int Dijkstra()
{
    int Bottleneck;
    pair < int, int > X;
    SetVector(DijkstraDistance, INF);
    Distance[Source] = 0;
    DijkstraDistance[Source] = 0;
    Father[Source] = -1;
    Q.push({0, Source});
    while(!Q.empty())
    {
        X = Q.top();
        Q.pop();
        if(DijkstraDistance[X.second] == -X.first)
            for(int &it : Edges[X.second])
                if(Graph[X.second][it] > 0 && DijkstraDistance[X.second] + Cost[X.second][it] + BellmanFordDistance[X.second] - BellmanFordDistance[it] < DijkstraDistance[it])
                {
                    DijkstraDistance[it] = DijkstraDistance[X.second] + Cost[X.second][it] + BellmanFordDistance[X.second] - BellmanFordDistance[it];
                    Distance[it] = Distance[X.second] + Cost[X.second][it];
                    Father[it] = X.second;
                    Q.push({-DijkstraDistance[it], it});
                }
    }

    memcpy(BellmanFordDistance, Distance, sizeof(int) * (N + 5));

    if(DijkstraDistance[Destination] == INF)
        return 0;

    Bottleneck = Graph[Father[Destination]][Destination];
    for(int x = Destination; Father[x] != -1; x = Father[x])
        Bottleneck = min(Bottleneck, Graph[Father[x]][x]);
    for(int x = Destination; x != Source; x = Father[x])
        Graph[Father[x]][x] -= Bottleneck, Graph[x][Father[x]] += Bottleneck;
    TotalFlow += Bottleneck * Distance[Destination];
    return 1;
}

int main()
{
    int x, y, c, w;
    in >> N >> M >> Source >> Destination;
    for(int i = 1; i <= M; i++)
    {
        in >> x >> y >> c >> w;
        Edges[x].push_back(y);
        Edges[y].push_back(x);
        Graph[x][y] = c;
        Cost[x][y] = w;
        Cost[y][x] = -w;
    }
    BellmanFord();
    while (Dijkstra());
    out << TotalFlow;
    return 0;
}