From ed319a8f85e721f8cbc5c037bde8c30361377308 Mon Sep 17 00:00:00 2001 From: eemoreira <112673452+eemoreira@users.noreply.github.com> Date: Thu, 29 Aug 2024 16:47:29 -0300 Subject: [PATCH] codigo da block cut tree (#166) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * codigo da block cut tree * tinha esquecido do clang format * Update Codigos/Grafos/Block-Cut-Tree/README.md Co-authored-by: João Oliveira <70975757+joaomarcosth9@users.noreply.github.com> --------- Co-authored-by: João Oliveira <70975757+joaomarcosth9@users.noreply.github.com> --- Codigos/Grafos/Block-Cut-Tree/README.md | 8 +++ .../Grafos/Block-Cut-Tree/block_cut_tree.cpp | 65 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 Codigos/Grafos/Block-Cut-Tree/README.md create mode 100644 Codigos/Grafos/Block-Cut-Tree/block_cut_tree.cpp diff --git a/Codigos/Grafos/Block-Cut-Tree/README.md b/Codigos/Grafos/Block-Cut-Tree/README.md new file mode 100644 index 00000000..6c40a631 --- /dev/null +++ b/Codigos/Grafos/Block-Cut-Tree/README.md @@ -0,0 +1,8 @@ +# [Block Cut Tree](block_cut_tree.cpp) + +Algoritmo que separa o grafo em componentes biconexas em $\mathcal{O}(V + E)$. + +- `id[u]` é o index do nodo `u` na Block Cut Tree. +- `is_articulation_point(u)` diz se o nodo `u` é ou não é um ponto de articulação. +- `number_of_splits(u)` diz a quantidade de componentes conexas que o grafo + terá se o nodo `u` for removido. diff --git a/Codigos/Grafos/Block-Cut-Tree/block_cut_tree.cpp b/Codigos/Grafos/Block-Cut-Tree/block_cut_tree.cpp new file mode 100644 index 00000000..9a1d403a --- /dev/null +++ b/Codigos/Grafos/Block-Cut-Tree/block_cut_tree.cpp @@ -0,0 +1,65 @@ +struct Bct { + int T; + vector tin, low, stk, art, id, splits; + vector> adj, g, comp, up; + int n, sz, m; + void build(int _n, int _m) { + n = _n, m = _m; + adj.resize(n); + } + void add_edge(int u, int v) { + adj[u].emplace_back(v); + adj[v].emplace_back(u); + } + void dfs(int u, int p) { + low[u] = tin[u] = ++T; + stk.emplace_back(u); + for (auto v : adj[u]) { + if (tin[v] == -1) { + dfs(v, u); + low[u] = min(low[u], low[v]); + if (low[v] >= tin[u]) { + int x; + sz++; + do { + assert(stk.size()); + x = stk.back(); + stk.pop_back(); + comp[x].emplace_back(sz); + } while (x != v); + comp[u].emplace_back(sz); + } + } else if (v != p) { + low[u] = min(low[u], tin[v]); + } + } + } + inline bool is_articulation_point(int u) { return art[id[u]]; } + inline int number_of_splits(int u) { return splits[id[u]]; } + void work() { + T = sz = 0; + stk.clear(); + tin.resize(n, -1); + comp.resize(n); + low.resize(n); + for (int i = 0; i < n; i++) + if (tin[i] == -1) dfs(i, 0); + art.resize(sz + n + 1); + splits.resize(n + sz + 1, 1); + id.resize(n); + g.resize(sz + n + 1); + for (int i = 0; i < n; i++) { + if ((int)comp[i].size() > 1) { + id[i] = ++sz; + art[id[i]] = 1; + splits[id[i]] = (int)comp[i].size(); + for (auto u : comp[i]) { + g[id[i]].emplace_back(u); + g[u].emplace_back(id[i]); + } + } else if (comp[i].size()) { + id[i] = comp[i][0]; + } + } + } +};