Cod sursa(job #2969291)

Utilizator StanCatalinStanCatalin StanCatalin Data 22 ianuarie 2023 20:12:20
Problema Componente biconexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.55 kb
#include <iostream>
#include <vector>
#include <fstream>
#include <queue>
#include <stack>
#include <algorithm>

using namespace std;

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

const int dim = 1e5 + 5;

int n,m, viz[dim], distante[dim], s, in_deg[dim], nivel[dim], niv_min[dim];
vector<int> vec_nocost[dim];
vector<int> vec_nocost_transpus[dim];
vector<int> vizitate_acum;

stack<int> st;

void Citeste_nocost() {
    in >> n >> m;
//    in >> s;
    for (int i=0, x, y; i<m; i++) {
        in >> x >> y;
        in_deg[y]++;
        vec_nocost[x].push_back(y);
        vec_nocost[y].push_back(x);

//        vec_nocost_transpus[y].push_back(x);
    }
}

void DFS(int nod) {
    viz[nod] = 1;
    for (auto y:vec_nocost[nod]) {
        if (!viz[y]) {
            DFS(y);
        }
    }
    st.push(nod);
}

void DFS_transpus(int nod) {
    viz[nod] = 1;
    vizitate_acum.push_back(nod);
    for (auto y:vec_nocost_transpus[nod]) {
        if (!viz[y]) {
            DFS_transpus(y);
        }
    }
}

void BFS(int start) {
    for (int i=1; i<=n; i++) {
        distante[i] = -1;
    }
    distante[start] = 0;
    queue<int> q;
    q.push(start);
    viz[start] = 1;
    while (!q.empty()) {
        int nod = q.front();
        q.pop();
        for (auto y:vec_nocost[nod]) {
            if (!viz[y]) {
                viz[y] = 1;
                distante[y] = distante[nod] + 1;
                q.push(y);
            }
        }
    }

    for (int i=1; i<=n; i++) {
        out << distante[i] << " ";
    }
}

int Nr_CompConexe() {
    int cnt = 0;
    for (int i=1; i<=n; i++) {
        if (!viz[i]) {
            cnt++;
            DFS(i);
        }
    }
    return cnt;
}


vector<int> SortareTopologicaBFS() {
    queue<int> q;
    vector<int> rasp;
    for (int i=1; i<=n; i++) {
        if (in_deg[i] == 0) {
            q.push(i);
        }
    }

    while (!q.empty()) {
        int nod = q.front();
        q.pop();
        rasp.push_back(nod);

        for (auto y:vec_nocost[nod]) {
            in_deg[y]--;
            if (in_deg[y] == 0) {
                q.push(y);
            }
        }
    }
    return rasp;
}

void AfisVector(vector<int> &vec) {
    for (auto y:vec) {
        out << y << " ";
    }
}

void ComponenteTareConexe() {
    for (int i=1; i<=n; i++) {
        if (!viz[i]) {
            DFS(i);
        }
    }
    for (int i=1; i<=n; i++) {
        viz[i] = 0;
    }
    vector<vector<int>> vec;
    while (!st.empty()) {
        int nod = st.top();

        st.pop();
        if (!viz[nod]) {
            vizitate_acum.clear();
            DFS_transpus(nod);
            vec.push_back(vizitate_acum);
        }
    }

    out << vec.size() << "\n";
    for (int i=0; i<vec.size(); i++) {
        for (auto y:vec[i]) {
            out << y << " ";
        }
        out << "\n";
    }
}

stack<pair<int,int>> st_biconex;
vector<vector<int>> rasp;

void DFS_NIVMIN_NIV(int nod) {

    niv_min[nod] = nivel[nod];
    viz[nod] = 1;
    for (auto y:vec_nocost[nod]) {
        if (!viz[y]) { // muchie de avansare
            st_biconex.push({nod, y});
            nivel[y] = 1 + nivel[nod];
            DFS_NIVMIN_NIV(y);

            niv_min[nod] = min(niv_min[nod], niv_min[y]);


            if (niv_min[y] > nivel[nod]) { /// muchie critica si nod e punct critic

            }

            if (niv_min[y] == niv_min[nod]) { /// nod e punct critic

            }

            if (niv_min[y] >= nivel[nod]) { /// nod e punct critic
                int a, b;
                vector<int> aux;
                do {
                    a = st_biconex.top().first;
                    b = st_biconex.top().second;
                    aux.push_back(a);
                    aux.push_back(b);
                    st_biconex.pop();
                } while (a != nod || b != y);

                rasp.push_back(aux);
            }


            if (niv_min[y] < nivel[nod]) { /// e pe un ciclu

            }

        } else {
            if (nivel[y] < nivel[nod] - 1) { /// muchie de intoarcere
                niv_min[nod] = min(niv_min[nod], nivel[y]);
            }
        }
    }
}
//
//void DFS(int nod, vector<vector<int>> &critice) {
//    viz[nod] = 1;
//    niv_min[nod] = nivel[nod];
//    for (auto y:vec[nod]) {
//        if (!viz[y]) {
//            nivel[y] = 1 + nivel[nod];
//            DFS(y, critice);
//            niv_min[nod] = min(niv_min[nod], niv_min[y]);
//
//            if (niv_min[y] > nivel[nod]) {
//                vector<int> a;
//                a.push_back(nod);
//                a.push_back(y);
//                critice.push_back(a);
//            }
//        } else {
//            if (nivel[y] < nivel[nod] - 1) {
//                niv_min[nod] = min(nivel[y], niv_min[nod]);
//            }
//        }
//    }
//}

void ComponenteBiconexe(int nod) {
    DFS_NIVMIN_NIV(1);
}

int main() {
    Citeste_nocost();
/*    vector<int> rasp = SortareTopologicaBFS();
    AfisVector(rasp);*/


//    /// sortare topologica cu DFS
//    for (int i=1; i<=n; i++) {
//        if (!viz[i] && in_deg[i] == 0) {
//            DFS(i);
//        }
//    }
//    while (!st.empty()) {
//        out << st.top() << " ";
//        st.pop();
//    }

//    ComponenteTareConexe();

// biconexe
    ComponenteBiconexe(1);
    out << rasp.size() << "\n";
    for (int i=0; i<rasp.size(); i++) {
        sort(rasp[i].begin(), rasp[i].end());
        for (int j=0; j<rasp[i].size(); j++) {
            int x = rasp[i][j];
            out << x << " ";
            while (j < rasp[i].size() && rasp[i][j] == x) {
                j++;
            }
            j--;
        }
        out << "\n";
    }
    return 0;
}