Mai intai trebuie sa te autentifici.

Cod sursa(job #2928454)

Utilizator cosminnnnnnnaDuca Cosmina cosminnnnnnna Data 22 octombrie 2022 22:41:03
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.15 kb
#include <bits/stdc++.h>

using namespace std;

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


class Graf {
public:
    int nrNoduri, nrMuchii;
    int nrCompConexe = 0;

    vector <vector<int>> listaAdiacenta; //memorez graful
    vector <int> nodViz; //aici marchez nodurile vizitate
    vector <int> nodMin; // pentru nod = i, nodMin[i] retine val min pe care l are un vecin al lui i din aceeasi comp
    vector <int> nodStiva; //nodStiva[i] retine daca nodul i se afla pe stiva
    deque <int> stiva; //pe stiva se mem nodurile care ar putea fi in aceeasi comp conexa cu nodul curent
    vector <vector<int>> componente; //retine comp conexe


    //constructor pt graf
    Graf (int nrNoduriNou, int nrMuchiiNou){
        this->nrNoduri = nrNoduriNou;
        this->nrMuchii = nrMuchiiNou;

        vector <int> v;

        for(auto i = 0 ; i <= nrNoduriNou ; i++)
        {
            nodViz.push_back(-1);
            nodMin.push_back(-1);
            nodStiva.push_back(0);
            listaAdiacenta.push_back(v);
        }
    }


    void listaNoua (int nod1, int nod2)
    {
        listaAdiacenta[nod1].push_back(nod2);
    }

    void DFS (int nod);

    void afisCompConexe();

};

void Graf :: DFS (int nod)
{
    static int idNou = 0;

    // se reitereaza nodurile
    nodViz[nod] = ++idNou;
    nodMin[nod] = idNou;
    stiva.push_back(nod); //pun nodul curent pe stiva
    nodStiva[nod] = 1; //retin ca l am pus pe stiva


//for (int & i : listaAdiacenta[nod])
    for (auto i = listaAdiacenta[nod].begin(); i != listaAdiacenta[nod].end(); i++)
    {
        //daca nodul nu a fost vizitat, se face DFS

        if (nodViz[*i] == -1)
        {
            DFS(*i);
            nodMin[nod] = fmin(nodMin[nod], nodMin[*i]);
        }

        //daca nodul e pe stiva, nu se mai face DFS
        else if (nodStiva[*i] == 1)
        {
            nodMin[nod] = fmin(nodMin[nod], nodViz[*i]);
        }
    }

    int aux;

    if(nodMin[nod] == nodViz[nod])
    {

        vector<int> v;
        componente.push_back(v);

        while(stiva.back() != nod)
        {
            aux = stiva.back(); //aux retine nodul curent
            componente[nrCompConexe].push_back(aux);   //se scot toate elementele de pe stiva pana la nodul curent inclusiv
            nodStiva[aux] = 0; // se marcheaza nodurile scoase de pe stiva
            stiva.pop_back();
        }

        aux = stiva.back();
        componente[nrCompConexe].push_back(aux);
        nodStiva[aux] = 0;
        stiva.pop_back();

        nrCompConexe++;
    }

}

void Graf::afisCompConexe()
{
    for (int poz = 0 ; poz < nrNoduri ; poz++)
    {
        if(nodViz[poz] == -1)
            DFS(poz);
    }

    fout << nrCompConexe << "\n";

    for(int i = 0 ; i < nrCompConexe ; i++)
    {
        
        for(auto poz = componente[i].begin(); poz!=componente[i].end(); poz++)
            fout << *poz + 1 << " ";
            fout << "\n";
        }

}


int main() {

    int nrNoduri, nrMuchii, nod1, nod2;
    fin >> nrNoduri >> nrMuchii;

    Graf gf(nrNoduri, nrMuchii);

    for(int i = 0 ; i < nrMuchii ; i++)
    {
        fin >> nod1 >> nod2;
        gf.listaNoua(nod1-1, nod2-1);
    }

    gf.afisCompConexe();

    return 0;
}