Cod sursa(job #2795569)

Utilizator StarkillerCalin Stafie Starkiller Data 6 noiembrie 2021 16:42:14
Problema Componente tare conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 8.55 kb
#include <bits/stdc++.h>
#define NIL -1

using namespace std;

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

class Graful_meu
{
    int _noduri;
    int _muchii;
    vector<vector<int>> lista_muchii;

public:
    Graful_meu();   // daca ni se da lista de adiacenta
    int Componente_conexe();
    void citire_muchii_neorientat();
    int citire_muchii_neorientat_cu_nod_start();
    int citire_muchii_orientat_cu_nod_start();
    void citire_muchii_orientat();
    void DFS(int start, bool vizitat[]);
    void BFS(int start);
    vector <vector<int>> Componente_Biconexe(int Start);
    void DFS_Componente_Biconexe(int nod_curent, stack<int>&stiva_noduri, vector<int>&low,
                                        vector<int>&discovery_time,vector<vector<int>>&all_biconex_components);
    vector<vector<int>> Componente_Tare_Conexe();
    void DFS_Componente_Tare_Conexe(int nod_curent, stack<int>&stiva_noduri, vector<bool>&is_part_of_a_connected_comp, vector<int>&low,
                                        vector<int>&discovery_time,vector<vector<int>>&all_strongly_connected_components);

};
Graful_meu::Graful_meu()
{
    _noduri = 0;
    _muchii = 0;
}
void Graful_meu::citire_muchii_neorientat()
{
    int x, y;
    fin >> _noduri;
    fin >> _muchii;
    lista_muchii.resize(_noduri+2);
    for(int i = 1 ; i <= _muchii ; ++i)
    {
        fin >> x >> y;
        lista_muchii[x].push_back(y);
        lista_muchii[y].push_back(x);
    }
}
void Graful_meu::citire_muchii_orientat()
{
    int x, y;
    fin >> _noduri;
    fin >> _muchii;
    lista_muchii.resize(_noduri+2);
    for(int i = 1 ; i <= _muchii ; ++i)
    {
        fin >> x >> y;
        lista_muchii[x].push_back(y);
    }
}
int Graful_meu::citire_muchii_orientat_cu_nod_start()
{
    int x, y, nod_start;
    fin >> _noduri;
    fin >> _muchii;
    fin >> nod_start;
    lista_muchii.resize(_noduri+2);
    for(int i = 1 ; i <= _muchii ; ++i)
    {
        fin >> x >> y;
        lista_muchii[x].push_back(y);
    }
    return nod_start;
}
int Graful_meu::citire_muchii_neorientat_cu_nod_start()
{
    int x, y, nod_start;
    fin >> _noduri;
    fin >> _muchii;
    fin >> nod_start;
    lista_muchii.resize(_noduri+2);
    for(int i = 1 ; i <= _muchii ; ++i)
    {
        fin >> x >> y;
        lista_muchii[x].push_back(y);
        lista_muchii[y].push_back(x);
    }
    return nod_start;
}

void Graful_meu::DFS(int start, bool vizitat[])
{
    vizitat[start] = 1;
    for(int nod_vecin : lista_muchii[start])
        if(vizitat[nod_vecin] == 0)
            DFS(nod_vecin, vizitat);

}
int Graful_meu::Componente_conexe()
{
    bool vizitat[_noduri + 2] = {0};
    int numar_componente_conexe = 0;
    for(int i = 1 ; i <= _noduri ; ++i)
        if (vizitat[i] == 0)
        {
            DFS(i, vizitat);
            ++numar_componente_conexe;
        }
    return numar_componente_conexe;
}

void Graful_meu::BFS(int start)
{
    bool vizitat[_noduri + 2] = {0};
    queue<int>coada_BFS;
    vector<int> drumuri_minime(_noduri + 2, -1);

    coada_BFS.push(start);
    vizitat[start] = 1;
    drumuri_minime[start] = 0;

    while(!coada_BFS.empty())
    {

        for(int nod_vecin : lista_muchii[start])
            if(vizitat[nod_vecin] == 0)
            {
                coada_BFS.push(nod_vecin);
                vizitat[nod_vecin] = 1;
                drumuri_minime[nod_vecin] = drumuri_minime[start] + 1;
            }
        coada_BFS.pop();
        start = coada_BFS.front();
    }

    for(int i = 1 ; i <= _noduri ; ++i)
        gout << drumuri_minime[i] << " ";
}

vector<vector<int>> Graful_meu::Componente_Biconexe(int Start)
{
    vector<int>discovery_time(_noduri + 2, NIL);
    vector<int>low(_noduri + 2, NIL);
    vector<vector<int>> all_biconex_components;
    stack<int>stiva_noduri;

    DFS_Componente_Biconexe(Start, stiva_noduri, low, discovery_time, all_biconex_components);
    return all_biconex_components;
}

void Graful_meu::DFS_Componente_Biconexe(int nod_curent, stack<int>&stiva_noduri, vector<int>&low,
                                        vector<int>&discovery_time,vector<vector<int>>&all_biconex_components)
{
    static int time = 0;
    low[nod_curent] = discovery_time[nod_curent] = ++time;
    stiva_noduri.push(nod_curent);

    for(auto vecin : lista_muchii[nod_curent])
    {
        if(discovery_time[vecin] == NIL)
        {
            DFS_Componente_Biconexe(vecin, stiva_noduri, low, discovery_time, all_biconex_components);

            low[nod_curent] = min(low[nod_curent], low[vecin]);
            if(low[vecin] >= discovery_time[nod_curent])
            {
                vector<int>one_biconex_component;
                int nod_stiva = stiva_noduri.top();
                stiva_noduri.pop();
                one_biconex_component.push_back(nod_stiva);
                while(nod_stiva != vecin)
                {
                    nod_stiva = stiva_noduri.top();
                    stiva_noduri.pop();
                    one_biconex_component.push_back(nod_stiva);
                }
                one_biconex_component.push_back(nod_curent);

                all_biconex_components.push_back(one_biconex_component);
            }
        }
        else
            low[nod_curent] = min(low[nod_curent], discovery_time[vecin]);
    }
}

vector<vector<int>> Graful_meu::Componente_Tare_Conexe()
{
    vector<int>discovery_time(_noduri + 2, NIL);
    vector<int>low(_noduri + 2, NIL);
    vector<vector<int>> all_strongly_connected_components;
    stack<int>stiva_noduri;
    vector<bool>is_part_of_a_connected_comp(_noduri + 2, false);

    for(int i = 1 ; i <= _noduri ; ++i)
        if(discovery_time[i] == NIL)
            DFS_Componente_Tare_Conexe(i, stiva_noduri, is_part_of_a_connected_comp, low, discovery_time, all_strongly_connected_components);

    return all_strongly_connected_components;
}
void Graful_meu::DFS_Componente_Tare_Conexe(int nod_curent, stack<int>&stiva_noduri, vector<bool>&is_part_of_a_connected_comp, vector<int>&low,
                                        vector<int>&discovery_time,vector<vector<int>>&all_stongly_connected_components)
{
    static int time = 0;
    low[nod_curent] = discovery_time[nod_curent] = ++time;
    stiva_noduri.push(nod_curent);

    for(auto vecin : lista_muchii[nod_curent])
    {
        if(discovery_time[vecin] == NIL)
        {
            DFS_Componente_Tare_Conexe(vecin, stiva_noduri, is_part_of_a_connected_comp, low, discovery_time, all_stongly_connected_components);

            low[nod_curent] = min(low[nod_curent], low[vecin]);
        }
        else
            if(is_part_of_a_connected_comp[vecin] == false)
                low[nod_curent] = min(low[nod_curent], discovery_time[vecin]);
    }

    if(low[nod_curent] == discovery_time[nod_curent])
    {
        vector<int>one_strongly_connected_component;
        int nod_stiva = stiva_noduri.top();
        while(nod_stiva != nod_curent)
        {
            one_strongly_connected_component.push_back(nod_stiva);
            is_part_of_a_connected_comp[nod_stiva] = true;
            stiva_noduri.pop();
            nod_stiva = stiva_noduri.top();
        }
        one_strongly_connected_component.push_back(nod_stiva);
        is_part_of_a_connected_comp[nod_stiva] = true;
        stiva_noduri.pop();

        all_stongly_connected_components.push_back(one_strongly_connected_component);
    }
}
int main()
{
    Graful_meu g;

    // DFS - Componente conexe
/*
    g.citire_muchii_neorientat();
    gout << g.Componente_conexe();
*/

    // BFS
/*
    int nod_start = g.citire_muchii_orientat_cu_nod_start();
    g.BFS(nod_start);
*/

    // Componente biconexe - Algoritm Tarjan modificat
/*
    g.citire_muchii_neorientat();
    vector<vector<int>>toate_componentele_biconexe = g.Componente_Biconexe(1);
    gout << toate_componentele_biconexe.size() << '\n';
    for(auto &one_biconex_comp : toate_componentele_biconexe)
    {
        for(auto element : one_biconex_comp)
            gout << element << " ";
        gout << '\n';
    }
*/
    // Componente tare conexe - Algoritm Tarjan
    g.citire_muchii_orientat();
    vector<vector<int>>toate_componentele_tare_conexe = g.Componente_Tare_Conexe();
    gout << toate_componentele_tare_conexe.size() << '\n';
    for(auto &one_strongly_connected_comp : toate_componentele_tare_conexe)
    {
        for(auto element : one_strongly_connected_comp)
            gout << element << " ";
        gout << '\n';
    }
    return 0;
}