Skip to content

Commit 9ab3609

Browse files
committed
Use stack for component collection
1 parent f90d418 commit 9ab3609

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

cp-algo/graph/tarjan.hpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
#include "../structures/csr.hpp"
55
#include <algorithm>
66
#include <cassert>
7+
#include <stack>
78
namespace cp_algo::graph {
89
enum node_state { unvisited, visiting, visited, blocked };
910
template<graph_type graph>
1011
struct tarjan_context {
1112
big_vector<int> tin, low;
1213
big_vector<node_state> state;
14+
std::stack<int> stack;
1315
graph const* g;
1416
int timer;
1517
structures::csr<node_index> components;
@@ -22,14 +24,14 @@ namespace cp_algo::graph {
2224
void on_exit(node_index) {}
2325

2426
void collect(node_index v) {
25-
state[v] = blocked;
26-
components.push(v);
27-
for(auto e: g->outgoing(v)) {
28-
node_index u = g->edge(e).to;
29-
if (state[u] != blocked && state[u] != visiting) {
30-
collect(u);
31-
}
32-
}
27+
components.new_row();
28+
node_index u;
29+
do {
30+
u = stack.top();
31+
stack.pop();
32+
state[u] = blocked;
33+
components.push(u);
34+
} while(u != v);
3335
}
3436
};
3537
template<template<typename> class Context, graph_type graph>
@@ -38,6 +40,7 @@ namespace cp_algo::graph {
3840
auto dfs = [&](this auto &&dfs, node_index v, edge_index ep = -1) -> void {
3941
context.state[v] = visiting;
4042
context.tin[v] = context.low[v] = context.timer++;
43+
context.stack.push(v);
4144
for(auto e: g.outgoing(v)) {
4245
if constexpr (undirected_graph_type<graph>) {
4346
if (ep == graph::opposite_idx(e)) {
@@ -70,7 +73,6 @@ namespace cp_algo::graph {
7073

7174
void on_exit(node_index v) {
7275
if (base::low[v] == base::tin[v]) {
73-
base::components.new_row();
7476
base::collect(v);
7577
}
7678
}
@@ -94,15 +96,13 @@ namespace cp_algo::graph {
9496
using base::base;
9597
void on_tree_edge(node_index v, node_index u) {
9698
if (base::low[u] >= base::tin[v]) {
97-
base::components.new_row();
9899
base::collect(u);
99100
base::components.push(v);
100101
}
101102
}
102103
void on_exit(node_index v) {
103104
if (std::empty(base::g->outgoing(v))) {
104-
base::components.new_row();
105-
base::components.push(v);
105+
base::collect(v);
106106
}
107107
}
108108
};

0 commit comments

Comments
 (0)