Cod sursa(job #1425191)

Utilizator dinuandAndrei-Mario Dinu dinuand Data 26 aprilie 2015 22:34:50
Problema Componente biconexe Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
/* Tarjan */
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <algorithm>
#include <utility>
#include <unordered_set>

#define MAXN 100001
#define undefined -1

using namespace std;
using Graph = vector<vector<int> >;

Graph G(MAXN);
vector<int> index(MAXN, undefined);
vector<int> lowlink(MAXN);
vector<bool> onstack(MAXN);
int N, M;

void tarjan(int source, 
            int& current_idx,
            int parent, 
            stack<pair<int, int> >& st,
            vector<unordered_set<int> > &bicomp)
{
    index[source] = lowlink[source] = current_idx;
    current_idx += 1;

    for (auto &node : G[source]) {

        if (node == parent) continue;

        if (index[node] == undefined) {
            st.emplace(make_pair(source, node));
            tarjan(node, current_idx, source, st, bicomp);

            lowlink[source] = min(lowlink[source], lowlink[node]);

            if (lowlink[node] >= index[source]) {
                unordered_set<int> comp;
                int parent, child;

                do {
                    comp.emplace((parent = st.top().first));
                    comp.emplace((child = st.top().second));

                    st.pop();
                } while(!st.empty() && parent != source && child != node);

                bicomp.emplace_back(comp);
            }

        } else {
            lowlink[source] = min(lowlink[source], index[node]);
        }
    }
}

int main()
{
    ifstream in("biconex.in");
    ofstream out("biconex.out");

    in >> N >> M;
    for (int i = 1; i <= M; i++) {
        int x, y;
        in >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }

    vector<unordered_set<int> > bicomp;
    int start_idx = 1;
    stack<pair<int, int> > st;

    for (int node = 1; node <= N; node++)
        if (index[node] == undefined)
            tarjan(node, start_idx, -1, st, bicomp);

    int bicomp_number = bicomp.size();
    out << bicomp_number << '\n';
    for (int i = 0; i < bicomp_number; i++) {
        for (auto &node : bicomp[i])
            out << node << " ";
        out << '\n';
    }

    return 0;
}