Cod sursa(job #2792689)

Utilizator amalia.gemanGeman Aamalia amalia.geman Data 2 noiembrie 2021 10:33:02
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.65 kb
#include <bits/stdc++.h>
#define NMax 100001

using namespace std;

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


bool vizDFS[NMax];

// Kosaraju
stack <int> S; // stiva pentru memorarea nodurilor in ordinea timpilor de final
bool vizDFST[NMax]; // pt graful transpus
vector <int> grT[NMax]; // liste de adiacenta ale grafului transpus
vector <int> componente[NMax];


class graf
{
   int nrNoduri, nrMuchii;
   bool orientat;
   vector <int> gr[NMax]; // liste de adiacenta ale grafului

public:
    graf(int n, int m, bool o); // constructor
    void Citire_Orientat();
    void Citire_Neorientat();
    void BFS(int s); // s - nodul de start
    void DFS(int s); // s - nodul de start
    void Comp_Conexe();
    void Graf_Transpus();
    void ParcurgereGrafInitial();
    void DFST(int s, int culoare); // s - nodul de start, dfs pe graful transpus
    void CTC(); // comp tare conexe
    void Afisare();
};



graf :: graf(int n, int m, bool o)
{
    nrNoduri = n;
    nrMuchii = m;
    orientat = o;
}

void graf :: Citire_Orientat()
{
    for(int i = 1; i <= nrMuchii; ++i)
    {
        int x, y;
        fin >> x >> y;
        gr[x].push_back(y);
    }
}

void graf :: Graf_Transpus()
{
    for(int i = 1; i <= nrNoduri; ++i)
        for(auto j : gr[i])
            grT[j].push_back(i);
}

void graf :: Citire_Neorientat()
{
    for(int i = 1; i <= nrMuchii; ++i)
    {
        int x, y;
        fin >> x >> y;
        gr[x].push_back(y);
        gr[y].push_back(x);
    }
}

void graf :: BFS(int s)
{
    bool viz[NMax] = {0};
    int distanta[NMax] = {0};
    queue <int> q;

    viz[s] = 1;
    q.push(s);

    while(!q.empty())
    {
        int k = q.front();  // elem din varful cozii
        q.pop();            // sterg elem din varful cozii
        for(auto i : gr[k])
            if(!viz[i])
            {
                viz[i] = 1;
                q.push(i);
                distanta[i] = distanta[k] + 1;
            }
    }

    for(int i = 1; i <= nrNoduri; ++i)
        if(viz[i])
            fout << distanta[i] << " ";
        else
            fout << -1 << " ";
}

void graf :: DFS(int s)
{
    vizDFS[s] = 1;
    for(auto i : gr[s])
        if(!vizDFS[i])
            DFS(i);

    // pentru CTC(Kosaraju) - stabilim timpul de finalizare pentru nodul s
    S.push(s);
}

void graf :: Comp_Conexe()
{
    int ct = 0;
    for(int i = 1; i <= nrNoduri; ++i)
        if(!vizDFS[i])
            {
                ct++;
                DFS(i);
            }
    fout << ct;
}

void graf :: ParcurgereGrafInitial()
{
    for(int i = 1; i <= nrNoduri; ++i)
        if(!vizDFS[i])
            DFS(i);
}

void graf :: DFST(int s, int ct)
{
    vizDFST[s] = 1;
    componente[ct].push_back(s);
    for(auto i : grT[s])
        if(!vizDFST[i])
            DFST(i, ct);
}

void graf :: CTC()
{
    int ct_ctc = 0;
    while(!S.empty())
    {
        int varf = S.top();
        S.pop();
        if(!vizDFST[varf])
        {
            ct_ctc ++;
            DFST(varf, ct_ctc);
        }
    }

    fout << ct_ctc << "\n";

    for(int i = 1; i <= ct_ctc; ++i)
    {
        for(auto j:componente[i])
                fout << j << " ";
        fout << "\n";
    }
}

void graf :: Afisare()
{
    for(int i=1; i <= nrNoduri; ++i)
    {
        fout << i << " : " ;
        for(auto j: gr[i])
            fout << j << " ";
        fout << "\n";
    }
}

int N, M;

int main()
{
    fin >> N >> M;
    graf G(N, M, 1);
    G.Citire_Orientat();
    G.Graf_Transpus();
    G.ParcurgereGrafInitial();
    G.CTC();

    return 0;
}