Cod sursa(job #2808411)

Utilizator pizzandreeaCiurescu Andreea pizzandreea Data 24 noiembrie 2021 23:53:55
Problema Sortare topologica Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.49 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>

#define MAX 100001

using namespace std;
ifstream fin ("sortaret.in");
ofstream fout("sortaret.out");


vector <int> compBiconexe[MAX];

vector <int> compTareConexe[MAX];
vector <int> AT[MAX];

class Graf{
    public:
    //date membre
        vector <int> A[MAX];    //liste de adiacenta
        int mM, mN;
        int nrComp;     //nr comp conexe
        static bool viz[MAX];
        static bool vizT[MAX];
        static int up[MAX];
        static int nivel[MAX];
        static int S[MAX];
        // static int ST[MAX];
        static int top;
        static int topT;
        int nrCompBiconexe;
        stack <int> ST;

        //constructor

        Graf(int N, int M){
            mN = N;
            mM = M;
            nrComp = 0;
            nrCompBiconexe = 0;

        }

        void CitireGNeorientat(){
            int x, y;

            for(int i = 1; i <= mM; i++){
                // citim muchiile
                fin >> x >> y;
                A[x].push_back(y);  //adaugam ambele noduri in lista celuilalt de adiacenta
                A[y].push_back(x);  //deoarece graful e neorientat
            }
        }

        void CitireGOrientat(){
            int x, y;
 
            for(int i = 1; i <= mM; i++){
                fin >> x >> y;
                A[x].push_back(y);
                AT[y].push_back(x);
            }
        }
        void DFS(int start);
        void ComponenteConexe();


        void DFS_Biconex(int start, int father);
        void AfisareBiconex();

        void DFST(int start, int comp);
        void CompTareConexe();

        void SortareTop();
        void AfisareTop();
        void DFSTop(int start);

        void AfisareViz();

};



bool Graf :: viz[MAX] ={0};
bool Graf :: vizT[MAX] ={0};
int Graf :: up[MAX] = {0};
int Graf :: nivel[MAX] = {0};
int Graf :: S[MAX] = {0};
// int Graf :: ST[MAX] = {0};
int Graf :: top = 0;
int Graf :: topT = 0;

void Graf :: DFS (int start){
    viz[start] = 1;
    // vizitam nodul din care plecam

    for(int i = 0; i < A[start].size(); i++){
        // parcurgem toti vecinii nodului start
        if(!viz[A[start][i]] ){
            // daca nu am mai vizitat acest vecin
            DFS(A[start][i]);
        }
    }
    // ST[++topT] = start;
    ST.push(start);
}


void Graf :: ComponenteConexe(){
    
    for(int i = 1; i <= mN; i++){
        if(!viz[i]){
            nrComp++;
            DFS(i);
        }
    }
}


void Graf :: DFS_Biconex(int start, int father){
    viz[start] = 1;
    // vizitam nodul din care plecam
    up[start] = nivel[start];
    S[++top] = start;

    for(int i = 0; i < A[start].size(); i++){
        // parcurgem toti vecinii nodului start
        if(i != father ){
            //daca nu e nodul din care am venit
            if(viz[A[start][i]]){

                // daca am mai vizitat acest vecin
                up[start] = min(up[start], nivel[A[start][i]]);
            }
            else{
                //daca nu a mai fost vizitat
                nivel[A[start][i]] = nivel[start] +1;
                DFS_Biconex(A[start][i], start);

                if(up[A[start][i]] >= nivel[start]){
                    nrCompBiconexe++;

                    while(top && S[top] != A[start][i]){
                        compBiconexe[nrCompBiconexe].push_back(S[top--]);
                    }
                    
                    compBiconexe[nrCompBiconexe].push_back(S[top--]);
                    compBiconexe[nrCompBiconexe].push_back(start);
                }
                up[start] = min(up[start], up[A[start][i]]);
            }
        }
    }
}

void Graf :: AfisareBiconex()
{
    fout << nrCompBiconexe << "\n";
    for ( int i = 1; i <= nrCompBiconexe; i++ ){
        for ( int j = 0; j < compBiconexe[i].size(); j++ )
            fout << compBiconexe[i][j] << " ";
        fout << "\n";
    }
}


void Graf :: DFST(int start, int comp){

    vizT[start] = 1;
    // fout << 1;
    compTareConexe[comp].push_back(start);
    for(int i = 0; i < AT[start].size(); i++){
        if(!vizT[AT[start][i]] )
            DFST(AT[start][i], comp);
    }

}

void Graf :: CompTareConexe(){
    
    ComponenteConexe();

    int x;
    int nrcomp = 0;

    while(!ST.empty()){
        // x = ST[topT--];
        x = ST.top();
        ST.pop();

        if(!vizT[x]){
            nrcomp++;
            DFST(x, nrcomp);
        }
    }

    fout << nrcomp<<"\n";
    for(int i = 1; i <= nrcomp; i++){
        for(int j = 0; j < compTareConexe[i].size(); j++){
            fout << compTareConexe[i][j] << " ";
        }
        fout << "\n";
    }
}

void Graf :: DFSTop(int start){
    int i;
	viz[start] = 1;
	for (i = 0; i < A[start].size(); i++)
		if (!viz[A[start][i]])
			DFSTop(A[start][i]);
	ST.push(start);
}

void  Graf :: AfisareTop(){
    while(!ST.empty()){
        fout << ST.top() << " ";
        ST.pop();

    }
}

void Graf :: SortareTop(){

   int i;
	for (i = 1; i <= mN; i++)
		if (!viz[i])
			DFSTop(i);
	while (!ST.empty())
	{
		fout << ST.top() << " ";
		ST.pop();
	}

} 

void Graf :: AfisareViz()
{
    for ( int i = 1; i <= mN; i++ )
    {
        fout << vizT[i];
    }
}



int main(){
    int N, M;
    fin >> N >> M;
    Graf G(N,M);
    G.CitireGOrientat();
        
    G.SortareTop();
    

    return 0;
}