From d7f3dafa12613fddcddbc5e9beb4188e8a6f7993 Mon Sep 17 00:00:00 2001 From: subcrip Date: Wed, 20 Nov 2024 14:47:57 +0000 Subject: [PATCH] Add graph/ebcc.cc Signed-off-by: subcrip --- graph/ebcc.cc | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 graph/ebcc.cc diff --git a/graph/ebcc.cc b/graph/ebcc.cc new file mode 100644 index 0000000..0cc6480 --- /dev/null +++ b/graph/ebcc.cc @@ -0,0 +1,98 @@ +// WARN: Input should be a simple graph +// +// Returns: (BCC count, indices of BCC of each vertex) +// +// BCC index starts from 1 +pair> ebcc(const vector>& ch) { + int n = ch.size() - 1; + vector c(n + 1); + + vector low(n + 1), dfn(n + 1); + vector vis(n + 1); + vector stack; + + int time = 0; + int cnt = 0; + + auto dfs = [&] (auto dfs, int v, int pa) -> void { + low[v] = dfn[v] = ++time; + stack.emplace_back(v); + vis[v] = 1; + for (auto&& u : ch[v]) { + if (u == pa) continue; + if (not dfn[u]) { + dfs(dfs, u, v); + chmin(low[v], low[u]); + } else if (vis[u]) { + chmin(low[v], dfn[u]); + } + } + if (dfn[v] == low[v]) { + cnt += 1; + c[v] = cnt; + while (stack.back() != v) { + c[stack.back()] = cnt; + vis[stack.back()] = 0; + stack.pop_back(); + } + stack.pop_back(); + } + }; + + for (int i = 1; i <= n; ++i) { + if (not dfn[i]) { + dfs(dfs, i, 0); + } + } + return { cnt, c }; +} + + +// INFO: This function treats vertex pairs that have multiple edges as eBCCs. +// +// Returns: (BCC count, indices of BCC of each vertex) +// +// BCC index starts from 1 +pair> ebcc_with_mult(const vector>& ch) { + int n = ch.size() - 1; + vector c(n + 1); + + vector low(n + 1), dfn(n + 1); + vector vis(n + 1); + vector stack; + + int time = 0; + int cnt = 0; + + auto dfs = [&] (auto dfs, int v, int prev_idx) -> void { + low[v] = dfn[v] = ++time; + stack.emplace_back(v); + vis[v] = 1; + for (auto&& [u, i] : ch[v]) { + if (i == prev_idx) continue; + if (not dfn[u]) { + dfs(dfs, u, i); + chmin(low[v], low[u]); + } else if (vis[u]) { + chmin(low[v], dfn[u]); + } + } + if (dfn[v] == low[v]) { + cnt += 1; + c[v] = cnt; + while (stack.back() != v) { + c[stack.back()] = cnt; + vis[stack.back()] = 0; + stack.pop_back(); + } + stack.pop_back(); + } + }; + + for (int i = 1; i <= n; ++i) { + if (not dfn[i]) { + dfs(dfs, i, -1); + } + } + return { cnt, c }; +}