50#include <lal/basic_types.hpp>
51#include <lal/graphs/rooted_tree.hpp>
52#include <lal/graphs/free_tree.hpp>
53#include <lal/detail/graphs/traversal.hpp>
73template <
class tree_t>
80 uint64_t *
const root_size
85 std::is_base_of_v<graphs::free_tree, tree_t> or
86 std::is_base_of_v<graphs::rooted_tree, tree_t>
94 node parent, child, new_root;
96 const node root_u = root_of[u];
97 const node root_v = root_of[v];
99 const uint64_t size_u = root_size[root_u];
100 const uint64_t size_v = root_size[root_v];
101 const uint64_t new_size = size_u + size_v;
103 if (size_u < size_v) {
104 root_of[root_u] = root_v;
108 root_size[new_root] = new_size;
111 parent = v; child = u;
114 root_of[root_v] = root_u;
118 root_size[new_root] = new_size;
121 parent = u; child = v;
128 bfs.set_process_current(
129 [&](
const BFS<tree_t>&,
const node w) ->
void { root_of[w] = new_root; }
131 bfs.set_visited(parent, 1);
145template <
class tree_t>
150 node *
const root_of,
151 uint64_t *
const root_size
156 std::is_base_of_v<graphs::free_tree, tree_t> or
157 std::is_base_of_v<graphs::rooted_tree, tree_t>
160 const auto n = t.get_num_nodes();
164 uint64_t size_current_root = n + 1;
165 node current_root = n + 1;
169 bfs.set_process_current(
170 [&](
const auto&,
const node w) {
171 root_of[w] = current_root;
176 for (
const auto& [u, v] : edges) {
177 if (bfs.node_was_visited(u)) {
continue; }
180 size_current_root = 0;
182 root_size[current_root] = size_current_root;
196template <
class tree_t>
200 node *
const root_of,
201 uint64_t *
const root_size
206 std::is_base_of_v<graphs::free_tree, tree_t> or
207 std::is_base_of_v<graphs::rooted_tree, tree_t>
210 const auto n = t.get_num_nodes();
214 uint64_t size_current_root = n + 1;
215 node current_root = n + 1;
219 bfs.set_process_current(
220 [&](
const auto&,
const node w) {
221 root_of[w] = current_root;
226 for (
node u = 0; u < n; ++u) {
227 if (bfs.node_was_visited(u)) {
continue; }
230 size_current_root = 0;
232 root_size[current_root] = size_current_root;
251template <
class tree_t>
257 node *
const root_of,
258 uint64_t *
const root_size
263 std::is_base_of_v<graphs::free_tree, tree_t> or
264 std::is_base_of_v<graphs::rooted_tree, tree_t>
269 assert(root_of[u] == root_of[v]);
272 const uint64_t size_uv = root_size[root_of[u]];
280 uint64_t size_cc_u = 0;
282 bfs.set_process_current(
283 [&](
const auto&,
const node w) ->
void {
290 root_size[u] = size_cc_u;
296 bfs.set_process_current(
297 [&](
const auto&,
const node w) ->
void {
303 root_size[v] = size_uv - size_cc_u;
317template <
class tree_t>
322 node *
const root_of,
323 uint64_t *
const root_size
328 std::is_base_of_v<graphs::free_tree, tree_t> or
329 std::is_base_of_v<graphs::rooted_tree, tree_t>
332 const auto n = t.get_num_nodes();
336 uint64_t size_current_cc = n + 1;
337 node current_root = n + 1;
341 bfs.set_process_current(
342 [&](
const auto&,
const node w) {
343 root_of[w] = current_root;
348 for (
const auto& [u, v] : edges) {
349 if (not bfs.node_was_visited(u)) {
353 root_size[u] = size_current_cc;
356 if (not bfs.node_was_visited(v)) {
360 root_size[v] = size_current_cc;
383template <
class tree_t>
388 node *
const root_of,
389 uint64_t *
const root_size
394 std::is_base_of_v<graphs::free_tree, tree_t> or
395 std::is_base_of_v<graphs::rooted_tree, tree_t>
398 uint64_t size_cc_v = 0;
399 bfs.set_process_current(
400 [&](
const auto&,
const node w) ->
void {
408 root_size[v] = size_cc_v;
427template <
typename tree_t>
432 node *
const root_of,
433 uint64_t *
const root_size
438 std::is_base_of_v<graphs::free_tree, tree_t> or
439 std::is_base_of_v<graphs::rooted_tree, tree_t>
445 bfs.set_visited(u, 1);
447 if constexpr (std::is_base_of_v<graphs::free_tree, tree_t>) {
448 for (
const node v : t.get_neighbors(u)) {
452 (bfs, v, root_of, root_size);
456 for (
const node v : t.get_in_neighbors(u)) {
460 (bfs, v, root_of, root_size);
462 for (
const node v : t.get_out_neighbors(u)) {
466 (bfs, v, root_of, root_size);
Abstract graph Breadth-First Search traversal.
Definition traversal.hpp:89
void update_unionfind_before_remove_edges_incident_to(BFS< tree_t > &bfs, const node v, node *const root_of, uint64_t *const root_size) noexcept
Update Union-Find after the removal of a vertex.
Definition union_find.hpp:385
void update_unionfind_after_add_rem_edges_bulk(const tree_t &t, node *const root_of, uint64_t *const root_size) noexcept
Update the Union-Find data structure after several edges have been operated in bulk.
Definition union_find.hpp:198
void update_unionfind_after_add_edges(const tree_t &t, const edge_list &edges, node *const root_of, uint64_t *const root_size) noexcept
Update the Union-Find data structure after the addition of several edges.
Definition union_find.hpp:147
void update_unionfind_after_remove_edge(const tree_t &t, const node u, const node v, node *const root_of, uint64_t *const root_size) noexcept
Updates Union-Find after the removal of an edge.
Definition union_find.hpp:253
void update_unionfind_after_remove_edges(const tree_t &t, const edge_list &edges, node *const root_of, uint64_t *const root_size) noexcept
Update the Union-Find data structure after the addition of several edges.
Definition union_find.hpp:319
void update_unionfind_after_add_edge(const tree_t &t, const node u, const node v, node *const root_of, uint64_t *const root_size) noexcept
Update the Union-Find data structure after the addition of an edge.
Definition union_find.hpp:75
Main namespace of the library.
Definition basic_types.hpp:48
std::vector< edge > edge_list
See Edge list page for further details.
Definition basic_types.hpp:60
uint64_t node
Node type. See Node / Vertex page for further details.
Definition basic_types.hpp:51