From be58eb41f130a41b3ef8f434fbbf473a0336c18e Mon Sep 17 00:00:00 2001 From: baluteshih Date: Sat, 6 Apr 2024 16:33:29 +0800 Subject: [PATCH] Update BCC_Vertex.cpp --- codebook/2_Graph/BCC_Vertex.cpp | 92 ++++++++++++++++----------------- codebook/content.tex | 2 +- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/codebook/2_Graph/BCC_Vertex.cpp b/codebook/2_Graph/BCC_Vertex.cpp index f1bc9f77..033fc758 100644 --- a/codebook/2_Graph/BCC_Vertex.cpp +++ b/codebook/2_Graph/BCC_Vertex.cpp @@ -1,46 +1,46 @@ -vector G[N]; // 1-base -vector nG[N * 2], bcc[N]; -int low[N], dfn[N], Time, st[N], top; -int bcc_id[N], bcc_cnt; // 1-base -bool is_cut[N]; // whether is av -bool cir[N * 2]; -void dfs(int u, int pa = -1) { - int child = 0; - low[u] = dfn[u] = ++Time; - st[top++] = u; - for (int v : G[u]) - if (!dfn[v]) { - dfs(v, u), ++child; - low[u] = min(low[u], low[v]); - if (dfn[u] <= low[v]) { - is_cut[u] = 1; - bcc[++bcc_cnt].clear(); - int t; - do { - bcc_id[t = st[--top]] = bcc_cnt; - bcc[bcc_cnt].push_back(t); - } while (t != v); - bcc_id[u] = bcc_cnt; - bcc[bcc_cnt].pb(u); - } - } else if (dfn[v] < dfn[u] && v != pa) - low[u] = min(low[u], dfn[v]); - if (pa == -1 && child < 2) is_cut[u] = 0; -} -void bcc_init(int n) { // TODO: init {nG, cir}[1..2n] - Time = bcc_cnt = top = 0; - for (int i = 1; i <= n; ++i) - G[i].clear(), dfn[i] = bcc_id[i] = is_cut[i] = 0; -} -void bcc_solve(int n) { - for (int i = 1; i <= n; ++i) - if (!dfn[i]) dfs(i); - // block-cut tree - for (int i = 1; i <= n; ++i) - if (is_cut[i]) - bcc_id[i] = ++bcc_cnt, cir[bcc_cnt] = 1; - for (int i = 1; i <= bcc_cnt && !cir[i]; ++i) - for (int j : bcc[i]) - if (is_cut[j]) - nG[i].pb(bcc_id[j]), nG[bcc_id[j]].pb(i); -} +struct BCC { // 0-base + int n, dft, nbcc; + vector low, dfn, bln, stk, is_ap, cir; + vector> G, bcc, nG; + void make_bcc(int u) { + bcc.emplace_back(1, u); + for (; stk.back() != u; stk.pop_back()) + bln[stk.back()] = nbcc, bcc[nbcc].pb(stk.back()); + stk.pop_back(), bln[u] = nbcc++; + } + void dfs(int u, int f) { + int child = 0; + low[u] = dfn[u] = ++dft, stk.pb(u); + for (int v : G[u]) + if (!dfn[v]) { + dfs(v, u), ++child; + low[u] = min(low[u], low[v]); + if (dfn[u] <= low[v]) { + is_ap[u] = 1, bln[u] = nbcc; + make_bcc(v), bcc.back().pb(u); + } + } else if (dfn[v] < dfn[u] && v != f) + low[u] = min(low[u], dfn[v]); + if (f == -1 && child < 2) is_ap[u] = 0; + if (f == -1 && child == 0) make_bcc(u); + } + BCC(int _n): n(_n), dft(), nbcc(), low(n), dfn(n), bln(n), is_ap(n), G(n) {} + void add_edge(int u, int v) { + G[u].pb(v), G[v].pb(u); + } + void solve() { + for (int i = 0; i < n; ++i) + if (!dfn[i]) dfs(i, -1); + } + void block_cut_tree() { + cir.resize(nbcc); + for (int i = 0; i < n; ++i) + if (is_ap[i]) + bln[i] = nbcc++; + cir.resize(nbcc, 1), nG.resize(nbcc); + for (int i = 0; i < nbcc && !cir[i]; ++i) + for (int j : bcc[i]) + if (is_ap[j]) + nG[i].pb(bln[j]), nG[bln[j]].pb(i); + } // up to 2 * n - 2 nodes!! bln[i] for id +}; diff --git a/codebook/content.tex b/codebook/content.tex index 5a45e2b6..c13f19f9 100644 --- a/codebook/content.tex +++ b/codebook/content.tex @@ -14,7 +14,7 @@ \subsection{Black Magic} \section{Graph} -\subsection{BCC Vertex*} % test by CF 102512 A +\subsection{BCC Vertex*} % test by Library Checker Biconnected Components, block-cut tree test by CF 102512 A \lstinputlisting{2_Graph/BCC_Vertex.cpp} \subsection{Bridge*} % test by Library Checker Two-Edge-Connected Components \lstinputlisting{2_Graph/Bridge.cpp}