Cod sursa(job #2797727)

Utilizator danielcirlanDaniel Cirlan danielcirlan Data 10 noiembrie 2021 15:19:44
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 7.46 kb
#include <iostream>
#include <vector>
#include <fstream>
#include <stack>

using namespace std;

ifstream f("ctc.in");
ofstream g("ctc.out");

class Graf{
    int numar_noduri;
    int numar_muchii;
    int start;
    vector<vector<int>> vecini;
public:
    Graf(){
        numar_muchii = 0;
        numar_noduri = 0;
        start = 0;
    };

    void citire_date_orientat_start();
    void citire_date_neorientat();
    void citire_date_orientat();
    Graf* citire_date_orientat_transpus();
    void bfs(int);
    void dfs(vector<bool>&,int);
    void dfs_topo(vector<bool>&, int, vector<int>&);
    void sortare_topologica();
    int numar_componente_conexe();
    int get_start();
    void componente_tare_conexe(Graf&);
    void sortare_topologica_ctc(vector<int>&);
    void afis();
    void dfs_comp(vector<bool>&, int, vector<vector<int>>&, int);
    void biconex();
    void dfs_biconex(vector<bool>&, int, int, vector<int>&, vector<int>&, stack<int>&, vector<vector<int>>&, int&);
};

int Graf::get_start(){
    return start;
}

void Graf::bfs(int start){
    vector<int> coada;
    vector<int> drum_min(numar_noduri+1,-1);
    vector<bool> vizitat(numar_noduri+1,false);
    drum_min[start] = 0;
    coada.push_back(start);
    vizitat[start] = true;

    int inc = 0, sf = 0;
    while(inc <= sf){
        for(int i = 0; i < vecini[coada[inc]].size(); i++)
            if(vizitat[vecini[coada[inc]][i]] == false){
                coada.push_back(vecini[coada[inc]][i]);
                sf++;
                drum_min[vecini[coada[inc]][i]] = drum_min[coada[inc]] + 1;
                vizitat[vecini[coada[inc]][i]] = true;
            }
        inc++;
    }

    for(int i = 1; i <= numar_noduri; i++)
        g<<drum_min[i]<<" ";
}

void Graf::dfs(vector<bool> &vizitat, int start){
    vizitat[start] = true;
    for(int i = 0; i < vecini[start].size(); i++)
        if(vizitat[vecini[start][i]] == false)
            dfs(vizitat,vecini[start][i]);
}

int Graf::numar_componente_conexe(){
    vector<bool> vizitat(numar_noduri+1, false);
    int cnt = 0;
    for(int i = 1; i <= numar_noduri; i++)
        if(vizitat[i] == false){
            cnt++; dfs(vizitat,i);
        }
    return cnt;
}

void Graf::citire_date_orientat_start(){
    f>>numar_noduri;
    f>>numar_muchii;
    f>>start;
    int n1,n2;
    vecini.resize(numar_noduri+1);
    for(int i = 0; i < numar_muchii; i++){
        f>>n1>>n2;
        vecini[n1].push_back(n2);
    }
}

void Graf::citire_date_neorientat(){
    f>>numar_noduri;
    f>>numar_muchii;
    int n1,n2;
    vecini.resize(numar_noduri+1);
    for(int i = 0; i < numar_muchii; i++){
        f>>n1>>n2;
        vecini[n1].push_back(n2);
        vecini[n2].push_back(n1);
    }
}

void Graf::dfs_topo(vector<bool> &vizitat, int start, vector<int> &stk){
    vizitat[start] = true;
    int i;
    for(i = 0; i < vecini[start].size(); i++)
        if(vizitat[vecini[start][i]] == false)
            dfs_topo(vizitat, vecini[start][i], stk);
    stk.push_back(start);
}

void Graf::sortare_topologica(){
    vector<bool> vizitat(numar_noduri+1,false);
    vector<int> stk;
    for(int i = 1; i <= numar_noduri; i++){
        if(vizitat[i] == false){
            dfs_topo(vizitat,i,stk);
        }
    }
    for(int i = stk.size() - 1; i >= 0; i--)
        g<<stk[i]<<" ";
}

void Graf::sortare_topologica_ctc(vector<int> &stk){
    vector<bool> vizitat(numar_noduri+1,false);
    for(int i = 1; i <= numar_noduri; i++){
        if(vizitat[i] == false){
            dfs_topo(vizitat,i,stk);
        }
    }
}


void Graf::dfs_comp(vector<bool> &vizitat, int start, vector<vector<int>> &comp, int cnt){
    vizitat[start] = true;
    comp[cnt].push_back(start);
    for(int i = 0; i < vecini[start].size(); i++)
        if(vizitat[vecini[start][i]] == false){
            dfs_comp(vizitat,vecini[start][i],comp,cnt);
        }
}

void Graf::componente_tare_conexe(Graf &transpus){
    vector<bool> vizitat(numar_noduri+1, false);
    vector<int> stk;
    int cnt = 0;
    vector<vector<int>> componente;
    componente.resize(numar_noduri+1);
    sortare_topologica_ctc(stk);
    for(int i = stk.size()-1; i >= 0 ; i--){
        cout<<stk[i]<<" ";
    }

    /// cod pt gasirea comp conexe
    for(int i = stk.size() - 1; i >= 0; i--)
        if(vizitat[stk[i]] == false){
            transpus.dfs_comp(vizitat,stk[i],componente,cnt);
            cnt++;
        }

    g<<cnt<<'\n';
    for(int i = 0; i < cnt; i++){
        for(int j = 0; j < componente[i].size(); j++)
            g<<componente[i][j]<<" ";
        g<<'\n';
    }
}

Graf* Graf::citire_date_orientat_transpus(){
    f>>numar_noduri;
    f>>numar_muchii;
    int n1,n2;
    vecini.resize(numar_noduri+1);
    Graf *b = new Graf();
    b->numar_muchii = this->numar_muchii;
    b->numar_noduri = this->numar_noduri;
    (b->vecini).resize(numar_noduri+1);
    for(int i = 0; i < numar_muchii; i++){
        f>>n1>>n2;
        vecini[n1].push_back(n2);
        (b->vecini)[n2].push_back(n1);
        ///cout<<(b->vecini)[n2][(b->vecini)[n2].size()-1]<<" ";
    }
    return b;
}

void Graf::afis(){
    cout<<numar_noduri<<" "<<numar_muchii<<'\n';
    for(int i = 1; i <= numar_noduri; i++){
        cout<<i<<": ";
        for(int j = 0; j < vecini[i].size(); j++)
            cout<<vecini[i][j]<<" ";
        cout<<'\n';
    }
}

void Graf::dfs_biconex(vector<bool> &vizitat, int fiu, int tata, vector<int> &nivel, vector<int> &nma, stack<int> &stk, vector<vector<int>> &comp, int &cnt){
    vizitat[fiu] = true;
    stk.push(fiu);
    nivel[fiu] = nivel[tata] + 1;
    nma[fiu] = nivel[fiu];
    int i;
    for(i = 0; i < vecini[fiu].size(); i++)
        if(vecini[fiu][i] != tata){
            if(vizitat[vecini[fiu][i]] == true){
                if(nma[fiu] > nivel[vecini[fiu][i]]) nma[fiu] = nivel[vecini[fiu][i]];
            }
            else{
                dfs_biconex(vizitat, vecini[fiu][i], fiu, nivel, nma, stk, comp, cnt);
                if(nma[fiu] > nma[vecini[fiu][i]]) nma[fiu] = nma[vecini[fiu][i]];

                if(nivel[fiu] <= nma[vecini[fiu][i]]){
                    while(stk.top() != vecini[fiu][i]){
                        comp[cnt].push_back(stk.top());
                        stk.pop();
                    }
                    comp[cnt].push_back(vecini[fiu][i]);
                    stk.pop();
                    comp[cnt].push_back(fiu);
                    cnt++;
                }
            }
        }
}

void Graf::biconex(){
    vector<vector<int>> comp;
    comp.resize(numar_noduri+1);
    vector<bool> vizitat(numar_noduri+1,false);
    stack<int> stk;
    vector<int> nivel(numar_noduri+1);
    vector<int> nma(numar_noduri+1);
    nivel[0] = 0;
    int cnt = 0;
    dfs_biconex(vizitat, 1, 0, nivel, nma, stk, comp, cnt);
    g<<cnt<<'\n';
    for(int i = 0; i < cnt; i++){
        for(int j = 0; j < comp[i].size(); j++)
            g<<comp[i][j]<<" ";
        g<<'\n';
    }
}

int main()
{
    Graf a;
    ///a.citire_date_start();
    ///a.bfs(a.get_start());
    ///a.citire_date_neorientat();
    ///g<<a.numar_componente_conexe();
    Graf *b = a.citire_date_orientat_transpus();
    ///b->afis();
    ///a.sortare_topologica();
    ///a.sortare_topologica();
    a.componente_tare_conexe(*b);
    ///a.sortare_topologica();
    ///a.citire_date_neorientat();
    ///a.biconex();
    return 0;
}