Cod sursa(job #2793172)

Utilizator bananamandaoneTudor Cosmin Oanea bananamandaone Data 3 noiembrie 2021 10:22:54
Problema Parcurgere DFS - componente conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 7.69 kb
#include <bits/stdc++.h>

using namespace std;

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


class graf {
private:
    int n, m;
    vector<int> h[100003];
    bitset<100003> viz;

    int k, dist[100003], nivel[100003], mic[100003];
    bool orientat = false;
    vector<int> transpus[100003];
    vector<int> ctc[100003];
    queue< pair<int, int> >q;
    stack<int> s;
    stack<int> s_biconex;
    vector<int> cbiconexe[100003];
    vector< vector<int> > muchii;

    void dfs(int nod);

    void dfsctc(int nod);

    void bfs(int s);

    void dfs_biconex(int nod, int tata);

    //void muchii_critice(int nod, int tata, vector< vector<int> >& h2);

public:
    graf()
    {
        n = m = k = 0;
        for(int i = 1; i <= 100000; i++)
            dist[i] = -1;
    }

    void set_graf(int noduri, int muchii, bool Orientat);

    void adauga_muchie(int x, int y);

    void componente_conexe();

    void distante(int s);

    void sortare_topologica();

    void componente_tare_conexe();

    void componente_biconexe();

    static void havel_hakimi();

    //static vector<vector<int>> criticalConnections(int n, vector<vector<int>>& connections);
};

graf g;

int main()
{
    /// dfs
    int n, m, x, y;

    fin >> n >> m;
    g.set_graf(n, m, false);

    for(int i = 1; i <= m; i++)
    {
        fin >> x >> y;
        g.adauga_muchie(x,y);
    }
    g.componente_conexe();

    /// bfs
    /*int n, m, s, x, y;

    fin >> n >> m >> s;
    g.set_graf(n, m, true);

    for(int i = 1; i <= m; i++)
    {
        fin >> x >> y;
        g.adauga_muchie(x,y);
    }
    g.distante(s);*/

    /// biconex
    /*int n, m, x, y;

    fin >> n >> m;
    g.set_graf(n, m, false);

    for(int i = 1; i <= m; i++)
    {
        fin >> x >> y;
        g.adauga_muchie(x,y);
    }
    g.componente_biconexe();*/

    /// ctc
    /*int n, m, x, y;

    fin >> n >> m;
    g.set_graf(n, m, true);

    for(int i = 1; i <= m; i++)
    {
        fin >> x >> y;
        g.adauga_muchie(x,y);
    }
    g.componente_tare_conexe();*/

    /// sortare topologica
    /*int n, m, s, x, y;

    fin >> n >> m;
    g.set_graf(n, m, true);

    for(int i = 1; i <= m; i++)
    {
        fin >> x >> y;
        g.adauga_muchie(x,y);
    }
    g.sortare_topologica();*/

    /// havel hakimi
    //graf::havel_hakimi();

    /// muchii critice [[0,1],[1,2],[2,0],[1,3]]
    //graf::criticalConnections(..);


    fin.close();
    fout.close();
    return 0;
}


void graf :: set_graf(int noduri, int muchii, bool Orientat)
{
    n = noduri;
    m = muchii;
    orientat = Orientat;
}

void graf :: adauga_muchie(int x, int y)
{
    if(orientat)
    {
        h[x].push_back(y);
        transpus[y].push_back(x); // ctc
    }
    else
    {
        h[x].push_back(y);
        h[y].push_back(x);
    }
}

void graf :: dfs(int nod)
{
    viz[nod] = 1;
    for(auto i : h[nod])
        if(!viz[i])
            dfs(i);

    // pentru sortarea topologica si ctc
    s.push(nod);
}

void graf :: dfsctc(int nod)
{
    viz[nod] = 1;
    ctc[k].push_back(nod);
    for(auto i : transpus[nod])
        if(!viz[i])
            dfsctc(i);
}

void graf :: bfs(int s)
{
    pair<int, int> nod;
    q.push({s, 0});
    viz[s] = 1;
    dist[s] = 0;

    while(!q.empty())
    {
        nod = q.front();
        dist[nod.first] = nod.second;
        q.pop();

        for(auto i : h[nod.first])
            if(!viz[i])
            {
                q.push({i, nod.second + 1});
                viz[i] = 1;
            }
    }
}

void graf :: componente_conexe()
{
    int nrc;
    nrc = 0;
    for(int i = 1; i <= n; i++)
        if(!viz[i])
        {
            dfs(i);
            nrc++;
        }
    fout << nrc << "\n";
}

void graf :: distante(int s)
{
    bfs(s);
    for(int i = 1; i <= n; i++)
        fout << dist[i] << " ";
    fout << "\n";
}

void graf :: sortare_topologica()
{
    for(int i = 1; i <= n; i++)
        if(!viz[i])
            dfs(i);

    while(!s.empty())
    {
        fout << s.top() << " ";
        s.pop();
    }
    fout << "\n";
}

void graf :: componente_tare_conexe() // kosaraju
{
    int top;
    for(int i = 1; i <= n; i++)
        if(!viz[i])
            dfs(i);

    viz.reset();
    while(!s.empty())
    {
        top = s.top();
        s.pop();
        if(!viz[top])
        {
            k++;
            dfsctc(top);
        }
    }

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

void graf :: dfs_biconex(int nod, int tata)
{
    viz[nod] = 1;
    s_biconex.push(nod);

    mic[nod] = nivel[nod] = nivel[tata] + 1;

    for(auto i : h[nod])
    {
        if(i != tata)
        {
            if(viz[i])
                mic[nod] = min(mic[nod], nivel[i]);
            else
            {
                dfs_biconex(i, nod);

                mic[nod] = min(mic[nod], mic[i]);

                if(nivel[nod] <= mic[i]) // o noua componenta biconexa
                {
                    k++;
                    while(s_biconex.top() != i)
                    {
                        cbiconexe[k].push_back(s_biconex.top());
                        s_biconex.pop();
                    }
                    s_biconex.pop();
                    cbiconexe[k].push_back(i);
                    cbiconexe[k].push_back(nod);
                }
            }
        }
    }
}

void graf :: componente_biconexe()
{
    nivel[0] = 0;
    dfs_biconex(1, 0);

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

void graf :: havel_hakimi()
{
    int lg, x, suma = 0;
    vector<int>v;
    fin >> lg;
    for(int i = 1; i <= lg; i++)
    {
        fin >> x;
        v.push_back(x);
        suma += x;
    }

    if(suma % 2 == 1)
    {
        fout << "Nu\n";
        return;
    }

    while(true)
    {
        if(v.size() == 0)
        {
            fout << "Da\n";
            return;
        }
        sort(v.begin(), v.end(), greater<int>());
        x = v[0];

        if((int)v.size() - 1 < x)
        {
            fout << "Nu\n";
            return;
        }
        for(int i = 1; i < x + 1; i++)
        {
            v[i]--;
            v[i - 1]= v[i];

            if(v[i] < 0)
            {
                fout << "Nu\n";
                return;
            }
        }
        v.pop_back();
    }
}

/*void graf :: muchii_critice(int nod, int tata, vector< vector<int> >& h2)
{
    viz[nod] = 1;

    mic[nod] = nivel[nod] = nivel[tata] + 1;

    for(int i = 0; i < h2[nod].size(); i++)
    {
        int vecin = h2[nod][i];

        if(!viz[vecin])
        {
            muchii_critice(vecin, nod, h2);

            mic[nod] = min(mic[nod], mic[vecin]);

            if(nivel[nod] < mic[vecin])
            {
                vector<int> muchie = {nod, vecin};
                muchii.push_back(vector<int>{nod, vecin});
            }
        }
        else if(vecin != tata)
        {
            mic[nod] = min(mic[nod], nivel[vecin]);
        }
    }
}

vector<vector<int>> graf :: criticalConnections(int n, vector<vector<int>>& connections)
{
    vector< vector<int> > h2(100003);
    for(int i = 0; i < connections.size(); i++)
    {
        h2[connections[i][0]].push_back(connections[i][1]);
        h2[connections[i][1]].push_back(connections[i][0]);
    }
    muchii_critice(1, 0, h2);
    return muchii;
}*/