Cod sursa(job #2796928)

Utilizator MihaelaDanilaDanila Mihaela MihaelaDanila Data 9 noiembrie 2021 01:09:10
Problema Componente biconexe Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.22 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <algorithm>

using namespace std;

class Graf{
private:
    int m_nrNoduri;
    vector<vector<int>> m_listeAdiacenta;
    vector<int> viz;
    vector<int> arrivalTimes;
    vector<int> lowLinkValues;
    vector<vector<int>> componenteBiconexe;
    stack<pair<int,int>> StivaMuchiiComponentaBiconexaCurenta;
public:
    void citireGrafNeorientat(char* fisier);

    void afisComponenteBiconexe(char* fisier);
    void DFSBiconexe(int nodCurent, int precedent, int pas);
};

void Graf::citireGrafNeorientat(char* fisier){
    ifstream f(fisier);
    int nrMuchii;

    f>>this->m_nrNoduri;
    this->m_listeAdiacenta.resize(this->m_nrNoduri+1);

    f>>nrMuchii;

    for(int i=0; i<nrMuchii; i++){
        int x,y;
        f>>x>>y;
        this->m_listeAdiacenta[x].push_back(y);
        this->m_listeAdiacenta[y].push_back(x);
    }
}

void Graf::DFSBiconexe(int nodCurent, int precedent, int pas){
    //marcam ca vizitat nodul curent
    arrivalTimes[nodCurent] = pas;

    //momentan nivelul minim de intoarcere e nivelul curent, adica pasul
    lowLinkValues[nodCurent] = pas;

    //parcurgem vecinii nodului curent
    for(int i=0; i<this->m_listeAdiacenta[nodCurent].size(); i++){
        int vecinCurent = this->m_listeAdiacenta[nodCurent][i];
        if(vecinCurent != precedent){
            //verificam pe ce fel de muchie suntem
            //daca vecinul curent a mai fost vizitat inseamna ca am dat de o muchie de intoarcere, altfel suntem pe o muchie in jos
            if(arrivalTimes[vecinCurent] == -1){
                //am dat de o noua muchie din componenta biconexa curenta, asa ca o adaugam in stiva
                StivaMuchiiComponentaBiconexaCurenta.push(make_pair(nodCurent, vecinCurent));
                //apelam DFS pentru vecinul curent
                DFSBiconexe(vecinCurent, nodCurent, pas + 1);
                //verificam daca atunci cand ne am dus mai departe in graf
                // am dat de o muchie de intoarcere care ne duce mai sus decat ne ducea nodul acesta inainte
                if(lowLinkValues[nodCurent] > lowLinkValues[vecinCurent]){
                    lowLinkValues[nodCurent] = lowLinkValues[vecinCurent];
                }
                //verificam daca am ajuns la finalul componentei biconexe
                if(lowLinkValues[vecinCurent] >= arrivalTimes[nodCurent]){
                    //trebuie sa adaugam noua componenta biconexa in vectorul de componenete biconexe
                    //si sa golim stiva cu muchiile componentei biconexe curente
                    vector<int> aux;
                    int aux1, aux2;
                    do{
                        aux1 = StivaMuchiiComponentaBiconexaCurenta.top().first;
                        aux2 = StivaMuchiiComponentaBiconexaCurenta.top().second;
                        aux.push_back(aux1);
                        aux.push_back(aux2);
                        StivaMuchiiComponentaBiconexaCurenta.pop();
                    } while (aux1 != nodCurent || aux2 != vecinCurent);
                    componenteBiconexe.push_back(aux);
                }
            }else{
                //avem o muchie de intoarcere, trebuie sa verificam daca nu cumva duce mai sus
                if(lowLinkValues[nodCurent] > arrivalTimes[vecinCurent]){
                    lowLinkValues[nodCurent] = arrivalTimes[vecinCurent];
                }
            }
        }
    }
}

void Graf::afisComponenteBiconexe(char* fisier){
    ofstream g(fisier);

    this->arrivalTimes.assign(this->m_nrNoduri+1,-1);
    this->lowLinkValues.resize(this->m_nrNoduri+1);

    this->DFSBiconexe(1,0,0);

    g<<this->componenteBiconexe.size()<<"\n";
    for(int i=0; i<this->componenteBiconexe.size(); i++){
        //componenteBiconexe[i].erase(unique(componenteBiconexe[i].begin(), componenteBiconexe[i].end()), componenteBiconexe[i].end());
        for(int j=0; j<this->componenteBiconexe[i].size(); j++){
            g<<this->componenteBiconexe[i][j]<<" ";
        }
        g<<"\n";
    }
}

int main()
{
    Graf g;
    g.citireGrafNeorientat("biconex.in");
    g.afisComponenteBiconexe("biconex.out");
    return 0;
}