Skip to content
c++
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 100005;

int n, m, tot;
vector<int> g[N];          // 原图邻接表
vector<int> adj[N * 2];      // 圆方树邻接表 (开 2N)

int dfn[N], low[N], timer;
int stk[N], top;

inline void add_tree_edge(int u, int v) {
    adj[u].push_back(v);
    adj[v].push_back(u);
}

void tarjan(int u) {
    dfn[u] = low[u] = ++timer;
    stk[++top] = u;

    for (int v : g[u]) {
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
            if (low[v] >= dfn[u]) {
                int sq = ++tot;
                add_tree_edge(u, sq);
                do{
                    add_tree_edge(stk[top],sq);
                }while(stk[top--]!=v);
            }
        } else {
            low[u] = min(low[u], dfn[v]);
        }
    }
}

void build_bct() {
    tot = n;
    timer = top = 0;
    for (int i = 1; i <= n; ++i) {
        if (!dfn[i]) {
            tarjan(i);
            if (top > 0) --top; // 弹出孤立根节点
        }
    }
}