44#include " ../structures/csr.hpp"
55#include < algorithm>
66#include < cassert>
7+ #include < stack>
78namespace 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