Cod sursa(job #2799285)

Utilizator SofeiAndreiSofei Andrei SofeiAndrei Data 12 noiembrie 2021 19:37:32
Problema Componente tare conexe Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 12.76 kb
#include <bits/stdc++.h>
#include <iostream>
#include <fstream>
using namespace std;
ifstream f("ctc.in");
ofstream g("ctc.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,int tata[], bool vizitat[], stack <pair <int,int> > &stiva_muchii, int nivel[],int nivel_minim[],vector<vector< int > >&solutie,int nivel_curent);
        void Muchii_Critice();
        void DFS_MC(int start,int tata[], bool vizitat[], stack <pair <int,int> > &stiva_muchii, int nivel[],int nivel_minim[],vector<pair <int,int> >&solutie,int nivel_curent);
};
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].resize(rezultat[Nr_comp_tare_conexe].size());
    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);
    rezultat.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++;
            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 nivel_minim[n+1];
    stack <pair <int,int> > stiva_muchii;
    int tata[n+1];

    for(int i=1;i<=n;i++){
        nivel[i]=-1;
    }
    for(int i=1;i<=n;i++){
        vizitat[i]=0;
    }
    for(int i=1;i<=n;i++){
        tata[i]=0;
    }
    vector<vector< int > >solutie;
    DFS3(1,tata, vizitat,stiva_muchii, nivel,nivel_minim,solutie,0);
    while(stiva_muchii.size()>0){///aici o sa ramana muchiile critice + cele care leaga noduri "cu un singur vecin"
        vector <int> temporar_noduri;
        temporar_noduri.push_back(stiva_muchii.top().first);
        temporar_noduri.push_back(stiva_muchii.top().second);
        solutie.push_back(temporar_noduri);
        stiva_muchii.pop();
    }
    g<<solutie.size()<<'\n';
    for(int i=0;i<solutie.size();i++){
        for(int j=0;j<solutie[i].size();j++){
            g<<solutie[i][j]<<" ";
        }
        g<<'\n';
    }

}
void graf :: DFS3(int start,int tata[], bool vizitat[], stack <pair <int,int> > &stiva_muchii, int nivel[],int nivel_minim[],vector<vector< int > >&solutie,int nivel_curent)
{
    vizitat[start]=1;
    nivel[start]=nivel_curent;
    nivel_minim[start]=nivel_curent;
    if(vecini[start].size()==1){///aici o sa ramana muchii critice care leaga un nod "cu un singur vecin" de vecinul sau, deci e muchie critica
        vector<int> temporar_noduri;
        temporar_noduri.push_back(stiva_muchii.top().first);
        temporar_noduri.push_back(stiva_muchii.top().second);
        solutie.push_back(temporar_noduri);
        stiva_muchii.pop();
    }
    else{
        for(int i=0;i<int(vecini[start].size());i++){
            if(vizitat[vecini[start][i]]==1 && nivel[vecini[start][i]]<nivel[start] && vecini[start][i] != tata[start]){
                stiva_muchii.push(make_pair(start,vecini[start][i]));
                nivel_minim[start]=min(nivel_minim[start],nivel[vecini[start][i]]+1);
                tata[start]=vecini[start][i];
            }
            else
            if(vizitat[vecini[start][i]]==0){
                tata[vecini[start][i]]=start;
                stiva_muchii.push(make_pair(start,vecini[start][i]));
                DFS3(vecini[start][i],tata,vizitat,stiva_muchii,nivel,nivel_minim,solutie,nivel_curent+1);
                if(nivel_minim[vecini[start][i]] <= nivel[start]){
                    vector<int> temporar_muchii[2];
                    vector<int> temporar_noduri;
                    do{
                        temporar_muchii[0].push_back(stiva_muchii.top().first);
                        temporar_muchii[1].push_back(stiva_muchii.top().second);
                        stiva_muchii.pop();
                    }while(stiva_muchii.top().first!=tata[vecini[start][i]]);
                    temporar_muchii[0].push_back(stiva_muchii.top().first);
                    temporar_muchii[1].push_back(stiva_muchii.top().second);
                    stiva_muchii.pop();
                    for(int j=0;j<temporar_muchii[1].size();j++){
                        temporar_noduri.push_back(temporar_muchii[0][j]);
                    }
                    solutie.push_back(temporar_noduri);
                }
            }
        }
    }
}
void graf :: Muchii_Critice()
{
    bool vizitat[n+1];
    int nivel[n+1];
    int nivel_minim[n+1];
    stack <pair <int,int> > stiva_muchii;
    int tata[n+1];

    for(int i=1;i<=n;i++){
        nivel[i]=-1;
    }
    for(int i=1;i<=n;i++){
        vizitat[i]=0;
    }
    for(int i=1;i<=n;i++){
        tata[i]=0;
    }
    vector<pair <int,int> >solutie;
    DFS_MC(1,tata, vizitat,stiva_muchii, nivel,nivel_minim,solutie,0);
    while(stiva_muchii.size()>0){///aici o sa ramana muchiile critice + cele care leaga noduri "cu un singur vecin"
        solutie.push_back(make_pair(stiva_muchii.top().first,stiva_muchii.top().second));
        stiva_muchii.pop();
    }
    g<<"[";
    for(int i=0;i<solutie.size();i++){
        g<<"["<<solutie[i].first<<","<<solutie[i].second<<"]";
        if(i!=solutie.size()-1){
            g<<",";
        }
        else
            g<<"]";
    }

}
void graf :: DFS_MC(int start,int tata[], bool vizitat[], stack <pair <int,int> > &stiva_muchii, int nivel[],int nivel_minim[],vector<pair <int,int> >&solutie,int nivel_curent)
{
    vizitat[start]=1;
    nivel[start]=nivel_curent;
    nivel_minim[start]=nivel_curent;
    if(vecini[start].size()==1){///aici o sa ramana muchii critice care leaga un nod "cu un singur vecin" de vecinul sau, deci e muchie critica
        solutie.push_back(make_pair(stiva_muchii.top().first,stiva_muchii.top().second));
        stiva_muchii.pop();
    }
    else{
        for(int i=0;i<int(vecini[start].size());i++){
            if(vizitat[vecini[start][i]]==1 && nivel[vecini[start][i]]<nivel[start] && vecini[start][i] != tata[start]){
                stiva_muchii.push(make_pair(start,vecini[start][i]));
                nivel_minim[start]=min(nivel_minim[start],nivel[vecini[start][i]]+1);
                tata[start]=vecini[start][i];
            }
            else
            if(vizitat[vecini[start][i]]==0){
                tata[vecini[start][i]]=start;
                stiva_muchii.push(make_pair(start,vecini[start][i]));
                DFS_MC(vecini[start][i],tata,vizitat,stiva_muchii,nivel,nivel_minim,solutie,nivel_curent+1);
                if(nivel_minim[vecini[start][i]] <= nivel[start]){
                    do{
                        stiva_muchii.pop();
                    }while(stiva_muchii.top().first!=tata[vecini[start][i]]);
                    stiva_muchii.pop();
                }
            }
        }
    }
}
bool Havel_Hakimi(vector<int>grade)
{
    sort(grade.begin(),grade.end());
    if(grade[grade.size()-1]>grade.size()-1){
        return false;
    }
    while(grade[0]>=0){
        int cel_cel_mai_mare_grad=grade[grade.size()-1];
        grade.pop_back();
        if(cel_cel_mai_mare_grad>grade.size()){
            return false;
        }
        for(int i=grade.size()-1;i>=0;i--){
            cel_cel_mai_mare_grad--;
            grade[i]--;
            if(cel_cel_mai_mare_grad==0){
                break;
            }
        }
        if(cel_cel_mai_mare_grad!=0){
            return false;
        }
        sort(grade.begin(),grade.end());
        while(*grade.begin()==0 && grade.size()!=0){
            grade.erase(grade.begin());
        }
        if(grade.size()==0 || grade[0]==0){
            return true;
        }
    }
    return false;
}
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();
    */
    ///Rezolvare Muchii Critice
    /*
    G.citire_graf_neorientat(m);
    G.Muchii_Critice();
    */
    ///Rezolvare Havel Hakimi
    /*
    vector <int> grade;
    cin>>n;
    for(int i=0;i<n;i++){
        int x;
        cin>>x;
        grade.push_back(x);
    }
    cout<<Havel_Hakimi(grade);
    */
    return 0;
}