Cod sursa(job #2795165)

Utilizator redikusTiganus Alexandru redikus Data 6 noiembrie 2021 00:54:04
Problema Componente biconexe Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 6.67 kb
#include <iostream>
#include <fstream>
#include <bits/stdc++.h>
using namespace std;

class graf{

    int noduri, muchii;
    vector<vector<int>> adiacenta;

public:
    graf(vector<vector<int>> listaAdiacenta, int noduri, int muchii): adiacenta(listaAdiacenta), noduri(noduri), muchii(muchii) {};

    vector<int> bfs(int start){
        vector<int> res(this->adiacenta.size(), -1);
        vector<int> vis(this->adiacenta.size());
        queue<int> q;
        vis[start] = 1;
        q.push(start);
        res[start] = 0;

        while(!q.empty()){
            int curr = q.front();
            q.pop();
            for (int i: adiacenta[curr])
                if (vis[i] == 0) {
                    vis[i] = 1;
                    q.push(i);
                    res[i] = res[curr] + 1;
                };
        }
        return res;
    }

    int dfs(){
        vector<int> vis(this->noduri);
        int res = 0;
        stack<int> s;
        for(int i=0; i<this->noduri; i++){
            if(vis[i] == 0){
                res++;
                vis[i]=1;
                s.push(i);
                while(!s.empty()){
                    int curr = s.top();
                    s.pop();
                    for(int i=adiacenta[curr].size()-1; i>=0; i--){
                        int nod = adiacenta[curr][i];
                        if(vis[nod] == 0){
                            vis[nod] = 1;
                            s.push(nod);
                        }
                    }
                }
            }
        }
        return res;
    }

    void dfsBiconex(int tata, vector<int>& timp, vector<int>& rev, stack<pair<int, int>>& s, int& timpcurent, vector<unordered_set<int>>& rasp){
        timpcurent++;
        timp[tata]=timpcurent;
        rev[tata]=timpcurent;
        for(int fiu:adiacenta[tata]){
            if(timp[fiu]==-1){
                s.push(make_pair(tata, fiu));
                dfsBiconex(fiu, timp, rev, s, timpcurent, rasp);
                rev[tata]=min(rev[tata], rev[fiu]);
                if((timp[tata]!=1 && rev[fiu]>=timp[tata]) || (timp[tata]==1 && adiacenta[tata].size()>1)){
                    pair<int, int> stop = make_pair(tata, fiu);
                    unordered_set<int> aux;
                    while(s.top() != stop){
                        aux.insert(s.top().first);
                        s.pop();
                    }
                    aux.insert(stop.first);
                    aux.insert(stop.second);
                    rasp.push_back(aux);
                    s.pop();
                }
            }
            else{
                rev[tata] = min(rev[tata], timp[fiu]);
                if(timp[fiu] < timp[tata]){
                    s.push(make_pair(tata, fiu));
                }
            }
        }
    }

    vector<unordered_set<int>> biconex(){
        vector<int> timp(noduri+1, -1), rev(noduri+1);
        stack<pair<int, int>> s;
        vector<unordered_set<int>> rasp;
        int timpo=0;
        //pt ca graful nu e neaparat conex trb sa facem de mai multe ori dfs
        for(int i=1; i<=noduri; i++){
            if(timp[i]==-1){
                dfsBiconex(i, timp, rev, s, timpo, rasp);
            }
            if(!s.empty()){
                unordered_set<int> aux;
                while(!s.empty()){
                    aux.insert(s.top().first);
                    aux.insert(s.top().second);
                    s.pop();
                }
                rasp.push_back(aux);
            }
        }
        return rasp;
    }

    void dfsCtc(int tata, vector<int>& timp, vector<int>& rev, stack<int>& s, int& timpcurent, vector<unordered_set<int>>& rasp, unordered_set<int>& check){
        timpcurent++;
        timp[tata]=timpcurent;
        rev[tata]=timpcurent;
        s.push(tata);
        check.insert(tata);
        for(int fiu:adiacenta[tata]){
            if(timp[fiu]==-1){
                dfsCtc(fiu, timp, rev, s, timpcurent, rasp, check);
                rev[tata]=min(rev[tata], rev[fiu]);
            }
            else if(check.find(fiu)!=check.end()){
                rev[tata] = min(rev[tata], timp[fiu]);
            }
        }
        if(timp[tata]==rev[tata]){
            while (s.top() != tata){
                cout << s.top() << " ";
                check.erase(s.top());
                s.pop();
            }
            cout << s.top() << "\n";
            check.erase(s.top());
            s.pop();
        }
    }

    vector<unordered_set<int>> ctc(){
        vector<int> timp(noduri+1, -1), rev(noduri+1);
        unordered_set<int> check;
        stack<int> s;
        vector<unordered_set<int>> rasp;
        int timpo=0;
        for(int i=1; i<=noduri; i++){
            if(timp[i]==-1){
                dfsCtc(i, timp, rev, s, timpo, rasp, check);
            }
        }
        return rasp;
    }

};

void bfsDriver(){

    ifstream in("bfs.in");
    ofstream out("bfs.out");

    int n, m, s;
    in>>n>>m>>s;
    vector<vector<int>> mat(n);

    for(int i=0; i<m; i++){
        int aux1, aux2;
        in>>aux1>>aux2;
        mat[aux1-1].push_back(aux2-1);
    }

    graf x(mat, n, m);
    for(int a:x.bfs(s-1)){
        out<<a<<" ";
    }
}

void dfsDriver(){
    ifstream in("dfs.in");
    ofstream out("dfs.out");

    int n, m;
    in>>n>>m;
    vector<vector<int>> mat(n);

    for(int i=0; i<m; i++){
        int aux1, aux2;
        in>>aux1>>aux2;
        mat[aux1-1].push_back(aux2-1);
        mat[aux2-1].push_back(aux1-1);
    }
    graf x(mat, n, m);
    out<<x.dfs();
}

void biconexDriver(){
    ifstream in("biconex.in");
    ofstream out("biconex.out");
    int n, m;
    in>>n>>m;
    vector<vector<int>> mat(n+1);

    for(int i=0; i<m; i++){
        int aux1, aux2;
        in>>aux1>>aux2;
        mat[aux1].push_back(aux2);
        mat[aux2].push_back(aux1);
    }
    graf x(mat, n, m);
    vector<unordered_set<int>> fin = x.biconex();
    out<<fin.size()<<'\n';
    for(auto i:fin){
        for(int j:i){
            out<<j<<" ";
        }
        out<<'\n';
    }
}

void ctcDriver(){
    ifstream in("ctc.in");
    ofstream out("ctc.out");

    int n, m;
    in>>n>>m;
    vector<vector<int>> mat(n+1);

    for(int i=0; i<m; i++){
        int aux1, aux2;
        in>>aux1>>aux2;
        mat[aux1].push_back(aux2);
        mat[aux2].push_back(aux1);
    }
    graf x(mat, n, m);
    vector<unordered_set<int>> fin = x.ctc();
    out<<fin.size()<<'\n';
    for(auto i:fin){
        for(int j:i){
            out<<j<<" ";
        }
        out<<'\n';
    }
}

int main(){
    biconexDriver();
    return 0;
}