-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* codigo da block cut tree * tinha esquecido do clang format * Update Codigos/Grafos/Block-Cut-Tree/README.md Co-authored-by: João Oliveira <[email protected]> --------- Co-authored-by: João Oliveira <[email protected]>
- Loading branch information
1 parent
c3b5cab
commit ed319a8
Showing
2 changed files
with
73 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
struct Bct { | ||
int T; | ||
vector<int> tin, low, stk, art, id, splits; | ||
vector<vector<int>> 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]; | ||
} | ||
} | ||
} | ||
}; |