Cod sursa(job #2806536)

Utilizator Costin_PintilieHoratiu-Costin-Petru Pintilie Costin_Pintilie Data 22 noiembrie 2021 18:59:24
Problema Componente biconexe Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.46 kb
#include <bits/stdc++.h>
using namespace std;



class Graph{
private:
        int n; //nr de noduri, nr de muchii, nodul de inceput
        int m;
        int s;
        vector<vector <int>> adj; // adj = adjacent (=liste de vecini)
        vector < vector<int> > comp_nmbr; // folosit la biconexe, vector de vectori ce reprezinta componentele biconexe
public:

    void BFS_read();
    void BFS();

    void DFS_read();
    void DFS();

    void biconex();
    void DFS_biconex(int node, int low[], int disc[], int parent[], bool visited[], int time,stack <pair<int,int> >& st  );
};


void Graph::biconex(){
    ifstream fin("biconex.in");
    fin>>n>>m;
    int x,y;
    adj.resize(n+1);
    for(int i = 0; i < m; i++){
        fin>>x>>y;
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    fin.close();

    //dfs
    stack < pair<int,int> > st;

    int *disc = new int[n+1];
    int *low = new int[n+1];
    int *parent = new int[n+1];
    bool visited[n+1] = {0};
    int time = 0;

    for (int i = 1; i <= n; i++){
        disc[i] = -1;
        low[i] = -1;
        parent[i] = -1;
    }

    for (int i = 1; i <= n; i++){
        if (visited[i] == false){
            DFS_biconex(i, low, disc, parent, visited, time, st);
        }

    }
    ofstream fout("biconex.out");
    fout<<comp_nmbr.size()<<"\n";

    for(auto comp : comp_nmbr){
        for(auto node: comp){
            fout<<node<<" ";
        }
        fout<<"\n";
    }

}

void Graph::DFS_biconex(int node, int low[], int disc[], int parent[], bool visited[], int time,stack <pair<int,int> >& st  ){
    disc[node] = time + 1; //timpul de descoperire in dfs
    low[node] = time + 1; // lungimea minima pt a ajunge din radacina dfs-ului la nod
    time++;
    visited[node] = 1;
    int children = 0;

    for(int i: adj[node] ){
            //cout<<i<<" ";
        if (visited[i] == false){
            children++;
            st.push({node,i});
            parent[i] = node;
            DFS_biconex(i, low, disc, parent, visited, time, st);
            low[node] = min(low[node], low[i]);

            if( (parent[node] == -1 && children > 1) || (disc[node] != -1 && low[i] >= disc[node] ) )
            {       /*^radacina                                ^restul nodurilor*/
                vector <int> components; // vector ajutator in care va fi stocata componenta biconexa curenta
                while(st.top().first != node && st.top().second != i){
                        components.push_back(st.top().second);
                        st.pop();
                }
                components.push_back(st.top().second);
                components.push_back(st.top().first);
                st.pop();
                comp_nmbr.push_back(components);

            }

        }else if (parent[node] != i  ){
                    low[node] = min(low[node], low[i]);
                }
    }

}


void Graph::DFS_read(){
    ifstream fin("dfs.in");
    fin>>n>>m;
    int x,y;
    adj.resize(n+1);
    for(int i = 0; i < m; i++){
        fin>>x>>y;
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    fin.close();



}

void Graph::DFS(){
    bool visited[n+1] = {0};
    queue<int> q;
    int conex = 0;

    for(int i = 1; i < n+1; i++){
        if(!visited[i]){
            conex++;
            q.push(i);
            while( !q.empty() ){
                int curr_node = q.front();
                visited[curr_node] = 1;
                q.pop();
                for(int j = 0; j < adj[curr_node].size(); j++){
                    if(!visited[ adj[ curr_node][j] ] )
                        q.push(adj[curr_node][j] );
                }
            }
        }
    }
    ofstream fout("dfs.out");
    fout<<conex;
    fout.close();

}

void Graph::BFS_read(){
    ifstream fin("bfs.in");
    fin>>n>>m>>s;
    int x,y;
    adj.resize(n+1);
    for(int i = 0; i < m; i++){
        fin>>x>>y;
        adj[x].push_back(y);
    }
    fin.close();
}

void Graph::BFS(){
    bool visited[n+1];
    int length[n+1];

    for(int i = 0; i < n+1; i++){
        visited[i] = false;
        length[i] = -1;
    }

    visited[s] = true;
    length[s] = 0;

    queue<int> q;
    q.push(s);

    while(!q.empty()){
        int curr_node = q.front();
        q.pop();
        int nr_vec = adj[curr_node].size();

        for(int i = 0; i<nr_vec;i++){
            int x = adj[curr_node][i];

            if(!visited[x]){
                visited[x] = true;
                q.push(x);
                length[x] = length[curr_node] + 1;
            }
        }
    }

    ofstream fout("bfs.out");
    for(int i = 1; i <= n; i++){
        fout<<length[i]<<" ";
    }
    fout.close();
}

int main()
{
    Graph test;
//    test.BFS_read();
//    test.BFS();
    test.biconex();


    return 0;
}

//Graph::Graph(){
//    n = m = 0;
//    adj.clear();
//}
//
//Graph::Graph(int n, int m){
//    this->n = n;
//    this->m = m;
//    this->adj.resize(n+1);
//}
//
//Graph Graph::trp(){
//    Graph trpG(n,m);
//    for(int i = 1; i < n + 1; i++){
//        int sz = adj[i].size();
//
//        for(int j = 0; j < sz; j++){
//            trpG.adj[j].push_back(i);
//        }
//    }
//    return trpG;
//}

//https://infoarena.ro/job_detail/2796384?action=view-source
//https://www.hackerearth.com/practice/algorithms/graphs/biconnected-components/tutorial/