Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
lrvideckis committed Nov 28, 2024
1 parent bcbf961 commit bac7e9c
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 30 deletions.
38 changes: 18 additions & 20 deletions library/graphs/functional_graph_processor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<pii> cyc_pos;
int i, j;
vi childs;
};
vector<node> t;
Expand All @@ -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];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit bac7e9c

Please sign in to comment.