Cod sursa(job #2959177)

Utilizator MoarcascosminMoarcas Cosmin Moarcascosmin Data 29 decembrie 2022 23:32:57
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.42 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

const int nMax = 1001;
const int mMax = 1001;

int n, m, sursa, destinatie, fluxTotal;

int capacitate[nMax][mMax];
int flux[nMax][mMax];

int tata[nMax];
vector<vector<int>>vecini;

void Citire()
{
    ifstream f("maxflow.in");

    f >> n >> m;

    vecini.resize(n + 1);

    sursa = 1;
    destinatie = n;

    int x, y, z;

    for(int i = 0; i < m; i++)
    {
        f >> x >> y >> z;

        vecini[x].push_back(y);
        vecini[y].push_back(x);
        capacitate[x][y] += z;
    }
}

// Un bfs in care returnez: 
//          - 1, daca exista drum de la sursa la destinatie prin am flux
//          - 0, daca nu exista drum de la sursa la destinatie

int Bfs()
{
    queue<int> coada;
    vector<bool> vizitat(n + 1, false);

    coada.push(sursa);
    vizitat[sursa] = true;

    while(!coada.empty())
    {
        int nodCurent = coada.front();
        coada.pop();

        for(auto vecin : vecini[nodCurent])
        {
            if(vizitat[vecin] || flux[nodCurent][vecin] == capacitate[nodCurent][vecin])
                continue;
            
            coada.push(vecin);
            vizitat[vecin] = true;
            tata[vecin] = nodCurent;
        }
    }
    return vizitat[destinatie];
}

// Determin min(capacitatea ramasa a fiecarui nod din drumul de la sursa la destinatie)
int CapacitateRamasaMinima()
{
    int minim = 10000000;

    for(int nod = destinatie; nod != sursa; nod = tata[nod])
    {
        minim = min(minim, capacitate[tata[nod]][nod] - flux[tata[nod]][nod]);
    }

    return minim;
}

void ActualizareFlux(int capacitateaRamasa)
{
    for(int nod = destinatie; nod != sursa; nod = tata[nod])
    {
        flux[tata[nod]][nod] += capacitateaRamasa;
        flux[nod][tata[nod]] -= capacitateaRamasa;
    }
}

void DeterminareFuxMaxim()
{
    while(Bfs())
    {
        for(auto vecin : vecini[destinatie])
        {
            if(flux[vecin][destinatie] == capacitate[vecin][destinatie])
                continue;

            int capacitateRamasaMin = CapacitateRamasaMinima();

            if(capacitateRamasaMin == 0)
                continue;

            ActualizareFlux(capacitateRamasaMin);  

            fluxTotal += capacitateRamasaMin;   
        }
    }
}

void Afisare()
{
    ofstream g("maxflow.out");
    g << fluxTotal;
}

int main()
{   
    Citire();
    DeterminareFuxMaxim();
    Afisare();

    return 0;
}