Cod sursa(job #2814417)

Utilizator Pop_MariaPop Maria Pop_Maria Data 8 decembrie 2021 01:47:48
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.42 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

class Graf
{
    int numar_noduri, numar_muchii;

public:

    void citire();
    int max_flow(vector <vector <pair <int, int>>>, int, int, int);
    int bfs_maxflow(int, int, vector <vector <int>>&, vector<int>&, vector <vector <int>>&, vector <int>&, vector <vector<int>>&);
};

int Graf :: bfs_maxflow(int sursa, int destinatie, vector <vector <int>>& capacitati, vector <int> &tata, vector <vector <int>>&flux, vector <int> &vizitat, vector <vector<int>>&rezidual)
{
    int a;
    queue <int> coada;
    coada.push(sursa);
    tata.assign(capacitati.size(), 0);
    tata[sursa] = -1;

    vizitat.clear();
    vizitat.resize(capacitati.size(), 0);

    vizitat[sursa] = 1;

    while(!tata[destinatie] && !coada.empty())
    {
        a = coada.front();
        coada.pop();

        for(int i : rezidual[a])
            if(capacitati[a][i] > flux[a][i] && !vizitat[i])
        {
            tata[i] = a;
            vizitat[i] = 1;
            coada.push(a);
        }
    }
    return tata[destinatie];

}

int Graf :: max_flow(vector <vector <pair <int, int>>> lista_adiacenta, int sursa, int destinatie, int capacitate_maxima)
{
    int maxim = 0, flux_drum, a;
    vector <int> vizitat(numar_noduri + 1, 0);
    vector <int> tata(numar_noduri + 1, 0);
    vector <vector <int>> rezidual(numar_noduri + 1);
    vector <vector <int>> capacitati(numar_noduri + 1, vector <int>(numar_noduri + 1, 0));
    vector <vector <int>> flux(numar_noduri + 1, vector <int>(numar_noduri + 1, 0));

    for(int i = 0; i < numar_noduri + 1; i++)
        for(int j = 0; j < lista_adiacenta[i].size(); j++)
    {
        capacitati[i][lista_adiacenta[i][j].first] = lista_adiacenta[i][j].second;
        rezidual[i].push_back(lista_adiacenta[i][j].first);
        rezidual[lista_adiacenta[i][j].first].push_back(i);
    }

    while(bfs_maxflow(sursa, destinatie, capacitati, tata, flux, vizitat, rezidual))
    {
        for(int i : rezidual[destinatie])
            if(flux[i][destinatie] < capacitati[i][destinatie] && vizitat[i])
        {
            flux_drum = capacitate_maxima;
            tata[destinatie] = i;

            for(int j = destinatie; j != sursa; j = tata[j])
            {
                a = tata[j];

                if(flux_drum > capacitati[a][j] - flux[a][j])
                    flux_drum = capacitati[a][j] - flux[a][j];
            }
            if(flux_drum)
            {
                for(int j = destinatie; j != sursa; j = tata[j])
            {
                a = tata[j];
                flux[a][j] += flux_drum;
                flux[j][a] -= flux_drum;
            }

            maxim += flux_drum;
            }

        }
    }

    return maxim;
}

void Graf :: citire()
{
    int nod1, nod2, capacitate;

    fin >> numar_noduri >> numar_muchii;

    vector <vector <pair <int, int>>> lista_adiacenta;
    lista_adiacenta.resize(numar_noduri + 1);

    for(int i = 0; i < numar_muchii; i++)
    {
        fin >> nod1 >> nod2 >> capacitate;
        lista_adiacenta[nod1].push_back(make_pair(nod2, capacitate));
    }

    fout << max_flow(lista_adiacenta, 1, numar_noduri - 1, 110001);
}

int main()
{
    Graf x;
    x.citire();

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

    return 0;
}