Cod sursa(job #2814930)

Utilizator ptr22222Petru Popescu ptr22222 Data 8 decembrie 2021 20:22:08
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.06 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>

using namespace std;

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

const int nmax = 1001;
const int inf = 1<<30;

class Graf
{
private:
    bool orientat;
    int nrNoduri;
    vector <int> listaAdiacenta[nmax];
    vector <pair <int, int>> listaAdiacentaCost[nmax];
    //vector <vector<int>> grafRezidual;
public:
    Graf(int nrNoduri = 0, bool orientat = false);
    void adaugaMuchie(int, int);
    void adaugaMuchieCost(int, int, int);
    void citireMuchii(int);
    void citireMuchiiCost(int);
    vector<int> BFS(int);
    void DFS(int, bool*);
    int nrComponenteConexe();
    void DFSStiva(int nodcurent, bool *, stack<int> &);
    void sortareTopologica();
    void TarjanCTC(int&, int, int*, int*, bool*, stack <int> &, vector<vector<int>> &);
    void CTC();
    void TarjanBC(int&, int, int, int*, int*, stack <int>&, vector<vector<int>>&);
    void BC();
    void TarjanMC(int&, int, int, int*, int*, vector<pair<int,int>>&);
    void MC();
    vector <int> citireHakimi();
    bool Hakimi(vector <int>);
    vector <int> Dijkstra(int);
    pair<int, vector <pair <int, int>>> Prim(int);
    vector <int> BellmanFord(int);
    void reuniune(int, int, vector<int>&, vector<int>&);
    int gasire(int, vector<int>&);
    void verifica(int, int, vector<int>&);
    void paduri();
    bool BFSFMax(int**, int*, int, int);
    int EdmondsKarp(int**, int, int);
    void citireAfisareEdmondsKarp(int, int, int);
};

Graf::Graf(int nrNoduri, bool orientat) : nrNoduri(nrNoduri), orientat(orientat)
{
    this->nrNoduri = nrNoduri;
    this->orientat = orientat;
}

void Graf::adaugaMuchie(int nod1, int nod2)
{
    listaAdiacenta[nod1].push_back(nod2);
}

bool Graf::BFSFMax(int** grafRezidual, int* parinte, int sursa, int destinatie)
{
    queue <int> coadaBFS;
    bool vizitatBFS[nmax] = {false};
    coadaBFS.push(sursa);
    vizitatBFS[sursa] = true;
    parinte[sursa] = -1;
    while(!coadaBFS.empty())
    {
        int nodCurent = coadaBFS.front();
        coadaBFS.pop();
        for(auto vecin:listaAdiacenta[nodCurent])
        {
            if(!vizitatBFS[vecin] && grafRezidual[nodCurent][vecin] > 0)
            {
                parinte[vecin] = nodCurent;
                vizitatBFS[vecin] = true;
                coadaBFS.push(vecin);
                if(vecin == destinatie)
                {
                    return true;
                }
            }
        }
    }
    return false;
}

int Graf::EdmondsKarp(int** grafRezidual, int sursa, int destinatie)
{
    int fluxMaximTotal = 0;
    int parinte[nmax];
    while(BFSFMax(grafRezidual, parinte, sursa, destinatie))
    {
        int fluxMaximDrum = inf;
        int nodCurent = destinatie;
        while(nodCurent != sursa)
        {
            fluxMaximDrum = min(fluxMaximDrum, grafRezidual[parinte[nodCurent]][nodCurent]);
            nodCurent = parinte[nodCurent];
        }
        fluxMaximTotal += fluxMaximDrum;
        nodCurent = destinatie;
        while(nodCurent != sursa)
        {
            grafRezidual[parinte[nodCurent]][nodCurent] -= fluxMaximDrum;
            grafRezidual[nodCurent][parinte[nodCurent]] += fluxMaximDrum;
            nodCurent = parinte[nodCurent];
        }
    }
    return fluxMaximTotal;
}

void Graf::citireAfisareEdmondsKarp(int nrMuchii, int sursa, int destinatie)
{
    int nod1, nod2, capacitateRez;
    int **grafRezidual = new int*[nmax + 1];
    for (int i = 1; i <= nmax; i++)
    {
        grafRezidual[i] = new int[nmax + 1];
    }
    for(int i = 1; i <=nmax; i++)
    {
        for(int j = 1; j <=nmax; j++)
        {
            grafRezidual[i][j] = 0;
        }
    }
    for(int i = 0; i < nrMuchii; i++) {
        in >> nod1 >> nod2 >> capacitateRez;
        adaugaMuchie(nod1, nod2);
        grafRezidual[nod1][nod2] = capacitateRez;
        adaugaMuchie(nod2, nod1);
    }
    out << EdmondsKarp(grafRezidual, sursa, destinatie);
    delete grafRezidual;
}


int main()
{
    int n, m;
    in >> n >> m;
    Graf g(n,true);
    g.citireAfisareEdmondsKarp(m,1,n);
    return 0;
}