Cod sursa(job #2798076)

Utilizator 6kmeleon6Luca Cordus 6kmeleon6 Data 10 noiembrie 2021 21:20:35
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 6.77 kb
#include <bits/stdc++.h>

using namespace std;
/*
/// FISIERE BFS
ifstream in("bfs.in");
ofstream out("bfs.out");

/// FISIERE DFS
ifstream in("dfs.in");
ofstream out("dfs.out");

/// FISIERE BICONEX
ifstream in("biconex.in");
ofstream out("biconex.out");
*/

/// FISIERE CTC
ifstream in("ctc.in");
ofstream out("ctc.out");

class Graf
{
    int nr_N, nr_M, S, V[100001];
    vector<int> adiac[100001];
    vector<vector<int>> GT, G; /// GT = GRAF TRANSPUS(PENTRU CTC)
    vector<int> nma; ///NIVEL MINIM ACCESIBIL
    vector<int> nivel;

public:

    /// Constructori
    Graf() : nr_N(0), nr_M(0) {}
    Graf(int N, int M) : nr_N(N), nr_M(M) {}

    void citire_or();
    void citire_neor();
    void citire_or_CTC();

    void BFS();

    void DFS(int, vector<int>&);
    void conexe();

    void nma_nivel(int, int, vector<vector<int>>&, vector<int>&, vector<int>&, stack<int>&, int&, vector<int>&);
    void Biconex();

    void CTC();
    void DFS_G_CTC(int, vector<int>&, vector<bool>&);
    void DFS_GT_CTC(int, vector<bool>&, vector<vector<int>>&, int&);
};

void Graf::citire_or()  /// CITIRE GRAF ORIENTAT
{
    in >> nr_N >> nr_M >> S;
    for (int i = 0; i < nr_M; i++)
    {
        int x, y;
        in >> x >> y;
        adiac[x].push_back(y);
    }
}

void Graf::citire_or_CTC()  /// CITIRE GRAF ORIENTAT PENTRU CTC
{
    in >> nr_N >> nr_M;
    G = GT = vector<vector<int>>(nr_N + 1);
    for (int i = 0; i < nr_M; i++)
    {
        int x, y;
        in >> x >> y;
        G[x].push_back(y);
        GT[y].push_back(x);
    }
}

void Graf::citire_neor()    /// CITIRE GRAF NEORIENTAT
{
    in >> nr_N >> nr_M;
    for (int i = 0; i < nr_M; i++)
    {
        int x, y;
        in >> x >> y;
        adiac[x].push_back(y);
        adiac[y].push_back(x);
    }
}

void Graf::BFS() /// BFS
{
    queue <int> coada;
    int nod;
    int vizitat[100001] = {};
    vizitat[S] = 1;
    coada.push(S);
    int cost[100001] = {};
    cost[S] = 0;///Costul la nodul de start este 0

    while(coada.size() > 0) ///Cat timp inca mai am noduri in graf
    {
        nod = coada.front();

        for(int j = 0; j < adiac[nod].size(); j++)
        {
            if(vizitat[adiac[nod][j]] == 0)
            {
                coada.push(adiac[nod][j]);
                cost[adiac[nod][j]] = cost[nod] + 1;
                vizitat[adiac[nod][j]]++;
            }
        }
        coada.pop();
    }

    for(int i = 1; i <= nr_N; i++)
    {
        if(vizitat[i] == 0) out << "-1 ";
        else out << cost[i] << " ";
    }
}

void Graf::DFS(int S, vector<int>& vizitat) /// DFS
{
    vizitat[S] = 1;
    for(int i = 0; i < adiac[S].size(); i++)
    {
        if (vizitat[adiac[S][i]] ==0)
        {
            ///cout << adiac[S][i] << " ";
            DFS(adiac[S][i], vizitat);
        }
    }
}

void Graf::conexe() /// NUMARARE COMPONENTE CONEXE PENTRU DFS
{
    vector<int> vizitat;
    int nr=0, i;
    for(i = 0; i <= nr_N; i++)
        vizitat.push_back(0);

    for(i = 1; i <= nr_N; i++)
    {
        if (vizitat[i] == 0)
        {
            DFS(i,vizitat);
            nr++;
        }
    }
    out << nr;
}

void Graf::nma_nivel(int k, int tata, vector<vector<int>>& componente_bi, vector<int>& nma, vector<int>& nivel, stack<int>& stiva, int& nr, vector<int>& V) /// BICONEX_DFS
{
    V[k] = 1;
    stiva.push(k);
    nivel[k] = nivel[tata] + 1;
    nma[k] = nivel[k];
    for(int i = 0; i < adiac[k].size(); i++)
    {
        int x = adiac[k][i];
        ///cout << "test ";
        if(x != tata)
        {
            if(V[x] == 1)
            {
                ///cout << k << " " << adiac[k][i] << " | ";
                if(nma[k] > nivel[x])
                    nma[k] = nma[x];
            }
            else
            {
                nma_nivel(adiac[k][i], k, componente_bi, nma, nivel, stiva, nr, V);
                if(nma[k] > nma[x])
                {
                    nma[k] = nma[adiac[k][i]];
                }
                if(nivel[k] <= nma[x])
                {
                    ///cout << k << " " << adiac[k][i] << " | ";
                    while (stiva.top() != x)
                    {
                        componente_bi[nr].push_back(stiva.top());
                        stiva.pop();
                    }
                    componente_bi[nr].push_back(x);
                    stiva.pop();
                    componente_bi[nr].push_back(k);
                    nr++;
                }
            }
        }
    }
}

void Graf::Biconex() /// BICONEX
{
    vector<vector<int>> componente_bi;
    componente_bi.resize(nr_N + 1);
    vector<int> nma(nr_N + 1), nivel(nr_N + 1), V(nr_N + 1);
    int nr = 0;
    stack<int> stiva;
    ///cout << "test";
    nma_nivel(1, 0, componente_bi, nma, nivel, stiva, nr, V);
    ///cout << "TEST";
    out << nr << '\n';
    for(int i = 0; i < nr; i++)
    {
        for(int j = 0; j < componente_bi[i].size(); j++)
        {
            out << componente_bi[i][j] << " ";
        }
        out << '\n';
    }
}

void Graf::DFS_G_CTC(int k, vector<int>& stiva_CTC, vector<bool>& V_CTC)
{
    V_CTC[k] = true;
    for(auto x : G[k])
        if(!V_CTC[x])
            DFS_G_CTC(x, stiva_CTC, V_CTC);
    stiva_CTC.push_back(k);
}

void Graf::DFS_GT_CTC(int k, vector<bool>& V_CTC, vector<vector<int>>& componente_tc, int& contor)
{
    V_CTC[k] = true;
    for(auto x : GT[k])
        if(!V_CTC[x])
            DFS_GT_CTC(x, V_CTC, componente_tc, contor);
    componente_tc[contor].push_back(k);
}

void Graf::CTC()
{
    /// adiac este G
    vector<vector<int>> componente_tc;
    componente_tc.resize(nr_N + 1);
    vector<int> stiva_CTC;
    vector<bool> V_CTC;
    int nr = 0;
    V_CTC = vector<bool> (nr_N + 1, false);
    for(int i = 1; i <= nr_N; i++)
    {
        if(!V_CTC[i])
            DFS_G_CTC(i, stiva_CTC, V_CTC);
    }
    V_CTC = vector<bool> (nr_N + 1, false);
    for(vector<int>::reverse_iterator it = stiva_CTC.rbegin() ; it != stiva_CTC.rend() ; it ++)
        if(!V_CTC[*it])
        {
            nr++;
            DFS_GT_CTC(*it, V_CTC, componente_tc, nr);
        }
    out << nr << '\n';
    for(int i = 0; i <= nr_N; i++)
    {
        if(componente_tc[i].size() >= 1)
        {
            for(int j = 0; j <componente_tc[i].size(); j++)
            {
                out << componente_tc[i][j] << " ";
            }
            out << '\n';
        }
    }
}
int main()
{
    Graf G;
    /*
    ///BFS
    G.citire_or();
    G.BFS();

    ///DFS
    G.citire_neor();
    G.conexe();

    ///Biconex
    G.citire_neor();
    G.Biconex();
    */

    ///CTC
    G.citire_or_CTC();
    G.CTC();

    return 0;
}