From bac7e9cdd8308e1e8bd5bb505346d573b8adabf2 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Wed, 27 Nov 2024 19:21:57 -0600 Subject: [PATCH] update --- library/graphs/functional_graph_processor.hpp | 38 +++++++++---------- .../handmade_tests/functional_graph.test.cpp | 18 ++++----- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/library/graphs/functional_graph_processor.hpp b/library/graphs/functional_graph_processor.hpp index 6694b159..71792d3e 100644 --- a/library/graphs/functional_graph_processor.hpp +++ b/library/graphs/functional_graph_processor.hpp @@ -3,17 +3,16 @@ //! @code //! // 0 <= a[i] < n //! auto [t2, cycle] = func_graph(a); -//! if (auto id = t2[v].cyc_pos) -//! assert(v == cycle[id->first][id->second]); +//! int root = cycle[t2[v].i][t2[v].j]; +//! bool is_on_cycle = (v == root); //! @endcode -//! t[v].root_of = first reachable node in a cycle +//! root = first reachable node on cycle //! t[v].childs = forest of reversed edges not in cycles //! @time O(n) //! @space O(n) struct func_graph { struct node { - int root_of; - optional cyc_pos; + int i, j; vi childs; }; vector t; @@ -22,26 +21,25 @@ struct func_graph { vi state(sz(a)); rep(i, 0, sz(a)) { if (state[i] == 0) { - int v = i; - while (state[v] == 0) { - state[v] = 1; - v = a[v]; + int u = i; + while (state[u] == 0) { + state[u] = 1; + u = a[u]; } - if (state[v] == 1) { + if (state[u] == 1) { cycle.emplace_back(); - while (state[v] == 1) { - t[v].root_of = v; - t[v].cyc_pos = { - sz(cycle) - 1, sz(cycle.back())}; - cycle.back().push_back(v); - state[v] = 2; - v = a[v]; + while (state[u] == 1) { + t[u].i = sz(cycle) - 1; + t[u].j = sz(cycle.back()); + cycle.back().push_back(u); + state[u] = 2; + u = a[u]; } } - int curr_root_of = t[v].root_of; - v = i; + int v = i; while (state[v] == 1) { - t[v].root_of = curr_root_of; + t[v].i = t[u].i; + t[v].j = t[u].j; t[a[v]].childs.push_back(v); state[v] = 2; v = a[v]; diff --git a/tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp b/tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp index ee3510ee..99486432 100644 --- a/tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp +++ b/tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp @@ -129,19 +129,17 @@ int main() { functional_graph_processor fgp(a); assert(cycle == fgp.cycle); for (int i = 0; i < n; i++) { - assert(t[i].root_of == fgp.root_of[i]); + int root = cycle[t[i].i][t[i].j]; assert(t[i].childs == fgp.abr[i]); - assert(t[i].cyc_pos.has_value() == - (fgp.cycle_id[i] != -1)); - if (auto id = t[i].cyc_pos) { - int cyc_len = ssize(cycle[id->first]); - assert(i == cycle[id->first][id->second]); + assert((root == i) == (fgp.cycle_id[i] != -1)); + if (root == i) { + assert(t[i].i == fgp.cycle_id[i]); + assert(t[i].j == fgp.cycle_pos[i]); + int cyc_len = ssize(cycle[t[i].i]); assert( - cycle[id->first][(id->second + 1) % cyc_len] == - a[i]); + cycle[t[i].i][(t[i].j + 1) % cyc_len] == a[i]); assert(fgp.cycle_prev[i] == - cycle[id->first] - [(id->second - 1 + cyc_len) % cyc_len]); + cycle[t[i].i][(t[i].j - 1 + cyc_len) % cyc_len]); } else { assert(fgp.cycle_prev[i] == -1); }