Cod sursa(job #2796701)

Utilizator razvanflorinPotcoveanu Florin-Razvan razvanflorin Data 8 noiembrie 2021 17:52:43
Problema Componente biconexe Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 7.31 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f;
ofstream g;

class Graf {

    int noduri, muchii;

    vector< vector<int> > lista;

    public:

    Graf(int numar_noduri, int numar_muchii, int aux);

    Graf(int numar_noduri, int numar_muchii);

    void out();

    void bfs(int start);

    void dfs(vector<bool> &vizitat, int start);

    void biconex();

    void dfs_biconex(int start, vector<bool> &vizitat, int niv, vector<int> &nivel, vector<int> &nivel_intoarcere, vector<int> &parinte, vector < pair <int, int> > &st, int &contor, vector<set<int>> &componeneteBiconexe);

};

void Graf :: out ()
{
    g << noduri << " " << muchii << endl;

    for(int i = 0; i < noduri; i++)
    {
        g << i << " : ";
        for(int j = 0 ; j < lista[i].size(); j++)
            g << lista[i][j] << " ";
        g << endl;
    }

}

Graf :: Graf (int numar_noduri, int numar_muchii, int aux)
{
    noduri = numar_noduri;
    muchii = numar_muchii;

    int nod_1, nod_2;

    lista.resize(numar_noduri + 1);

    for(int i = 1; i <= numar_muchii; i++)
    {
        f >> nod_1 >> nod_2;

        lista[nod_1].push_back(nod_2);
    }
}

Graf :: Graf (int numar_noduri, int numar_muchii)
{
    noduri = numar_noduri;
    muchii = numar_muchii;

    int nod_1, nod_2;

    lista.resize(numar_noduri + 1);

    for(int i = 1; i <= numar_muchii; i++)
    {
        f >> nod_1 >> nod_2;

        lista[nod_1].push_back(nod_2);
        lista[nod_2].push_back(nod_1);
    }
}

void Graf :: bfs(int start)
{
    int distanta[noduri + 1];

    for(int index = 1; index <= noduri; index++)
        distanta[index] = -1;

    bool vizitat[noduri + 1] = {false};

    queue<int> q;

    q.push(start);

    distanta[start] = 0;

    vizitat[start] = true;

    while(!q.empty())
    {
        int nod = q.front();
        q.pop();
        for(int index = 0; index < lista[nod].size(); index++)
            if(vizitat[lista[nod][index]] == false)
            {
                q.push(lista[nod][index]);
                vizitat[lista[nod][index]] = true;
                distanta[lista[nod][index]] = distanta[nod] + 1;
            }
    }

    for(int secondIndex = 1; secondIndex <= noduri; secondIndex++)
        g << distanta[secondIndex] << " ";
}

void Graf :: dfs(vector<bool> &vizitat, int start)
{
    vizitat[start] = true;
    for(int index = 0; index < lista[start].size(); index++)
        if(vizitat[lista[start][index]] == false)
            dfs(vizitat, lista[start][index]);
}

void Graf :: biconex()
{
    int contor = 0;

    vector<bool> vizitat;
    vizitat.resize(noduri + 1);

    vector<int> nivel;
    vector<int> nivel_intoarcere;
    vector<int> parinte;
    vector< set <int> > componenteBiconexe;

    nivel.resize(noduri + 1);
    nivel_intoarcere.resize(noduri + 1);
    parinte.resize(noduri + 1);

    vector < pair<int, int>> st;

    for(int index = 1; index <= noduri; index++)
    {
        nivel[index] = 0;
        nivel_intoarcere[index] = 0;
        vizitat[index] = false;
    }


    for(int index = 1; index <= noduri; index++)
    {
        if(vizitat[index] == false)
        {
            dfs_biconex(index, vizitat, 1, nivel, nivel_intoarcere, parinte, st, contor, componenteBiconexe);

            int j = 0;

            set<int> set_aux;

            while(!st.empty())
            {
                j = 1;
                set_aux.insert(st.back().first);
                set_aux.insert(st.back().second);
                st.pop_back();
            }

            componenteBiconexe.push_back(set_aux);

            if(j == 1)
            {
                contor++;
            }
        }
    }

    g << contor << endl;

    for(int index = 0; index < componenteBiconexe.size(); index++)
    {
        set<int>::iterator it;

        for(it = componenteBiconexe[index].begin(); it != componenteBiconexe[index].end(); it++)
            g << *it << " ";
        g << endl;
    }
}

void Graf :: dfs_biconex(int start, vector<bool> &vizitat, int niv, vector<int> &nivel, vector<int> &nivel_intoarcere, vector<int> &parinte, vector < pair < int, int> > &st, int &contor, vector<set<int>> &componenteBiconexe)
{

    vizitat[start] = true;
    nivel[start] = nivel_intoarcere[start] = niv;

    int copil = 0;

    for(int index = 0; index < lista[start].size(); index++)
    {
        int nod = lista[start][index];

        if(vizitat[nod] == false)
            {
                copil++;
                parinte[nod] = start;

                pair<int, int> aux;
                aux.first = start;
                aux.second = nod;

                st.push_back(aux);

                dfs_biconex(nod, vizitat, niv + 1, nivel, nivel_intoarcere, parinte, st, contor, componenteBiconexe);

                nivel_intoarcere[start] = min(nivel_intoarcere[start], nivel_intoarcere[nod]);

                if( (nivel[start] == 1 && copil > 1) || (nivel[start] > 1 && nivel_intoarcere[nod] >= nivel[start]) )
                {
                    set<int> set_aux;

                    while(st.back().first != start || st.back().second != nod)
                    {
                        set_aux.insert(st.back().first);
                        set_aux.insert(st.back().second);
                        st.pop_back();
                    }


                    set_aux.insert(st.back().first);
                    set_aux.insert(st.back().second);

                    componenteBiconexe.push_back(set_aux);

                    st.pop_back();
                    contor++;
                }
            }
        else if(nod != parinte[start])
        {
            nivel_intoarcere[start] = min(nivel_intoarcere[start], nivel[nod]);
            if(nivel[nod] < nivel[start])
            {
                pair<int, int> aux;
                aux.first = start;
                aux.second = nod;

                st.push_back(aux);
            }
        }
    }
}

int main()
{
    int problema = 3;

    if(problema == 1)
    {
        f.open ("bfs.in", std::ifstream::in);
        g.open ("bfs.out", std::ifstream::out);

        int n, m, s;

        f >> n >> m >> s;

        Graf graf(n, m, s);

        graf.bfs(s);

        f.close();

        g.close();

    }

    if(problema == 2)
    {
        int n, m;

        f.open ("dfs.in", std::ifstream::in);
        g.open ("dfs.out", std::ifstream::out);

        f >> n >> m;

        vector<bool> vizitat;

        vizitat.resize(n + 1);

        for(int index = 1; index <= n; index++)
            vizitat[index] = false;

        Graf graf(n, m);

        int contor = 0;

        for(int index = 1; index <= n; index++)
        {
            if(vizitat[index] == false)
                {
                    graf.dfs(vizitat, index);
                    contor++;
                }
        }

        g << contor;

        f.close();
        g.close();
    }

    if(problema == 3)
    {
        int n, m;

        f.open ("biconex.in", std::ifstream::in);
        g.open ("biconex.out", std::ifstream::out);

        f >> n >> m;

        Graf graf(n, m);

        graf.biconex();

        f.close();
        g.close();
    }

    return 0;
}