Cod sursa(job #2798769)

Utilizator SofeiAndreiSofei Andrei SofeiAndrei Data 11 noiembrie 2021 20:54:59
Problema Componente biconexe Scor 18
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 9.05 kb
#include <bits/stdc++.h>
#include <iostream>
#include <fstream>
using namespace std;
ifstream f("biconex.in");
ofstream g("biconex.out");
class graf
{
    private:
        int n;
        vector<vector< int > > vecini;
        int grad_int[100001];
        int grad_ext[100001];
    public:
        graf(int n);
        void citire_graf_orientat(int m);
        void citire_graf_neorientat(int m);
        void BFS(int start);
        void DFS(int start, bool vizitat[]);
        int nr_comp_conexe();
        void sortare_topologica();
        void ctc();
        void DFS2(int start, int vizitat[], stack <int>& stiva);
        void DFS_Transpus(int start, int vizitat[],vector <vector<int> > vecini_transpus,vector <vector<int> >& rezultat, int &Nr_comp_tare_conexe);
        void Componente_Biconexe();
        void DFS3(int start, bool vizitat[], int stiva_noduri[], int& Nr_Elem_Stiva, int stiva_muchii[][2], int& Nr_Muchii_Stiva, int nivel[]);
};
graf :: graf(int N)
{
    n=N;
    vecini.resize(n+1);
    for(int i=1;i<=n;i++){
        grad_int[i]=0;
        grad_ext[i]=0;
    }
}
void graf :: citire_graf_orientat(int M)
{
    int a,b;
    for(int i=1;i<=M;i++){
        f>>a>>b;
        grad_ext[a]++;
        grad_int[b]++;
        vecini[a].push_back(b);
    }
}
void graf :: citire_graf_neorientat(int m)
{
    int a,b;
    for(int i=1;i<=m;i++){
        f>>a>>b;
        grad_ext[a]++;
        grad_ext[b]++;
        grad_int[a]++;
        grad_int[b]++;
        vecini[a].push_back(b);
        vecini[b].push_back(a);
    }
}
void graf :: BFS(int start)
{
    queue <int> coada;
    int distanta[n+1];
    for(int i=1;i<=n;i++){
        distanta[i]=-1;
    }
    coada.push(start);
    distanta[start]=0;
    while(coada.empty()==0){
        for(int i=0;i<int(vecini[coada.front()].size());i++){
            if(distanta[vecini[coada.front()][i]]==-1){
                coada.push(vecini[coada.front()][i]);
                distanta[vecini[coada.front()][i]]=distanta[coada.front()]+1;
            }
        }
        coada.pop();
    }
    for(int i=1;i<=n;i++){
        g<<distanta[i]<<" ";
    }
}
int graf :: nr_comp_conexe()
{
    bool vizitat[n+1];
    int Nr=0;
    for(int i=1;i<=n;i++){
        vizitat[i]=0;
    }
    for(int i=1;i<=n;i++){
        if(vizitat[i]==0){
            Nr++;
            DFS(i, vizitat);
        }
    }
    return Nr;
}
void graf :: DFS(int start, bool vizitat[])
{
    vizitat[start]=1;
    for(int i=0;i<int(vecini[start].size());i++){
        if(vizitat[vecini[start][i]]==0){
            vizitat[vecini[start][i]]=1;
            DFS(vecini[start][i],vizitat);
        }
    }
}

void graf :: sortare_topologica()
{
    vector<int> rezolvare;
    bool vizitat[n+1];
    for(int i=1;i<=n;i++){
        vizitat[i]=0;
    }
    while(rezolvare.size()<n){
        for(int i=1;i<=n && rezolvare.size()<n;i++){
            if(grad_int[i]==0 && vizitat[i]==0){
                rezolvare.push_back(i);
                vizitat[i]=1;
                for(int j=0;j<int(vecini[i].size());j++){
                    grad_int[vecini[i][j]]--;
                }
            }
        }
    }
    for(int i=0;i<n;i++){
        g<<rezolvare[i]<<" ";
    }
}
void graf :: DFS2(int start, int vizitat[], stack <int>& stiva)
{
    vizitat[start]=1;
    for(int i=0;i<int(vecini[start].size());i++){
        if(vizitat[vecini[start][i]]==0){
            vizitat[vecini[start][i]]=1;
            DFS2(vecini[start][i],vizitat,stiva);
        }
    }
    stiva.push(start);
}
void graf :: DFS_Transpus(int start, int vizitat[],vector <vector<int> > vecini_transpus,vector <vector<int> >& rezultat, int &Nr_comp_tare_conexe)
{
    vizitat[start]=2;
    rezultat[Nr_comp_tare_conexe].push_back(start);
    for(int i=0;i<int(vecini_transpus[start].size());i++){
        if(vizitat[vecini_transpus[start][i]]==1){
            DFS_Transpus(vecini_transpus[start][i],vizitat,vecini_transpus,rezultat, Nr_comp_tare_conexe);
        }
    }
}
void graf :: ctc()
{
    vector <vector<int> > rezultat;
    stack <int> stiva;
    int vizitat[n+1];
    int Nr_comp_tare_conexe=0;
    for(int i=1;i<=n;i++){
        vizitat[i]=0;
    }
    vector <vector<int> > vecini_transpus;
    vecini_transpus.resize(n+1);
    for(int i=1;i<=n;i++){
        for(int j=0;j<vecini[i].size();j++){
            vecini_transpus[vecini[i][j]].push_back(i);
        }
    }
    for(int i=1;i<=n;i++){
        if(vizitat[i]==0){
            DFS2(i,vizitat,stiva);
        }
    }
    while(stiva.size()>0){
        if(vizitat[stiva.top()]==1){
            Nr_comp_tare_conexe++;
            rezultat.resize(Nr_comp_tare_conexe+1);
            DFS_Transpus(stiva.top(),vizitat,vecini_transpus,rezultat, Nr_comp_tare_conexe);
        }
        stiva.pop();
    }
    g<<Nr_comp_tare_conexe<<'\n';
    for(int i=1;i<=Nr_comp_tare_conexe;i++){
        for(int j=0;j<int(rezultat[i].size());j++){
            g<<rezultat[i][j]<<" ";
        }
        g<<'\n';
    }
}
void graf :: Componente_Biconexe()
{
    bool vizitat[n+1];
    int nivel[n+1];
    int stiva_noduri[n+1];
    int stiva_muchii[n+1][2];
    int Nr_Elem_Stiva=0;
    int Nr_Muchii_Stiva=0;

    vector<vector< int > >solutie;
    int nr_componente=0;

    for(int i=1;i<=n;i++){
        vizitat[i]=0;
    }
    Nr_Elem_Stiva=1;
    stiva_noduri[1]=1;
    nivel[1]=0;
    DFS3(1, vizitat, stiva_noduri, Nr_Elem_Stiva,stiva_muchii,Nr_Muchii_Stiva, nivel);
    /*
    for(int i=1;i<=Nr_Elem_Stiva;i++){
        cout<<stiva_noduri[i]<<" ";
    }
    cout<<"Muchii:"<<'\n';
    for(int i=1;i<=Nr_Muchii_Stiva;i++){
        cout<<stiva_muchii[i][0]<<" "<<stiva_muchii[i][1]<<'\n';
    }
    cout<<endl<<endl<<endl;
    */
    int indice=Nr_Muchii_Stiva;
    int unde_am_ramas_la_muchii=indice;
    int NIVEL_COPIL=0;
    int NIVEL_STRAMOS=0;
    bool OK;
    while(indice>0){
        OK=0;
        for(int i=0;i<int(vecini[stiva_muchii[indice][1]].size());i++){
            if(vecini[stiva_muchii[indice][1]][i] != stiva_muchii[indice][0] && nivel[vecini[stiva_muchii[indice][1]][i]] !=-1 && nivel[vecini[stiva_muchii[indice][1]][i]] < nivel[stiva_muchii[indice][1]]){
                OK=1;
                NIVEL_COPIL=nivel[stiva_muchii[indice][1]];
                NIVEL_STRAMOS=nivel[vecini[stiva_muchii[indice][1]][i]];
            }
        }
        if(OK==0){
            nr_componente++;
            solutie.resize(nr_componente+1);
            solutie[nr_componente].push_back(stiva_muchii[indice][0]);
            for(int i=indice;i<=unde_am_ramas_la_muchii;i++){
                solutie[nr_componente].push_back(stiva_muchii[indice][1]);
                nivel[stiva_muchii[indice][1]]=-1;
            }
            unde_am_ramas_la_muchii=indice;
            indice--;
        }
        else{
            nr_componente++;
            solutie.resize(nr_componente+1);
            while(NIVEL_COPIL>NIVEL_STRAMOS){
                if(nivel[stiva_muchii[indice][1]]!=-1 && nivel[stiva_muchii[indice][1]]>nivel[stiva_muchii[indice][0]]){
                    solutie[nr_componente].push_back(stiva_muchii[indice][1]);
                    nivel[stiva_muchii[indice][1]]=-1;
                }
                indice--;
                NIVEL_COPIL--;
            }
            if(indice!=0){
                solutie[nr_componente].push_back(stiva_muchii[indice][1]);
            }
            else
                solutie[nr_componente].push_back(1);
            unde_am_ramas_la_muchii=indice;
        }
    }
    g<<nr_componente<<'\n';
    for(int i=1;i<=nr_componente;i++){
        for(int j=0;j<solutie[i].size();j++){
            g<<solutie[i][j]<<" ";
        }
        g<<'\n';
    }
}
void graf :: DFS3(int start, bool vizitat[], int stiva_noduri[], int& Nr_Elem_Stiva, int stiva_muchii[][2], int& Nr_Muchii_Stiva, int nivel[])
{
    vizitat[start]=1;
    for(int i=0;i<int(vecini[start].size());i++){
        if(vizitat[vecini[start][i]]==0){
            nivel[vecini[start][i]]=nivel[start]+1;
            Nr_Elem_Stiva++;
            stiva_noduri[Nr_Elem_Stiva]=vecini[start][i];
            Nr_Muchii_Stiva++;
            stiva_muchii[Nr_Muchii_Stiva][0]=start;
            stiva_muchii[Nr_Muchii_Stiva][1]=vecini[start][i];
            DFS3(vecini[start][i],vizitat, stiva_noduri, Nr_Elem_Stiva,stiva_muchii,Nr_Muchii_Stiva, nivel);
        }
    }
    //TREBUIE SA VAD AIA CU MUCHIILE DE INTOARCERE
}
int n,m,S;
int main ()
{

    f>>n>>m;
    graf G(n);
    //Rezolvare problema BFS
    //f>>S;
    //G.citire_graf_orientat(m);
    //G.BFS(S);

    //Rezolvare problema DFS - Componente Conexe
    //G.citire_graf_neorientat(m);
    //g<<G.nr_comp_conexe();

    //Rezolvare Sortare Topologica
    /*
    G.citire_graf_orientat(m);
    G.sortare_topologica();
    */
    //Rezolvare Componente Tare Conexe
    /*
    G.citire_graf_orientat(m);
    G.ctc();
    */
    //Rezolvare Componente Biconexe
    G.citire_graf_neorientat(m);
    G.Componente_Biconexe();
    return 0;
}