Skip to content

Commit cdb9aed

Browse files
committed
Split Tarjan context
1 parent c6a9e44 commit cdb9aed

File tree

2 files changed

+68
-25
lines changed

2 files changed

+68
-25
lines changed

cp-algo/graph/dfs_time.hpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#ifndef CP_ALGO_GRAPH_DFS_TIME_HPP
2+
#define CP_ALGO_GRAPH_DFS_TIME_HPP
3+
#include "dfs.hpp"
4+
#include "base.hpp"
5+
namespace cp_algo::graph {
6+
// Context that maintains discovery time (tin)
7+
template<graph_type graph>
8+
struct dfs_time_context: dfs_context<graph> {
9+
using base = dfs_context<graph>;
10+
big_vector<int> tin;
11+
int timer;
12+
13+
dfs_time_context(graph const& g): base(g), tin(g.n()), timer(0) {}
14+
15+
void on_enter(node_index v) {
16+
tin[v] = timer++;
17+
}
18+
};
19+
20+
// Context that maintains both discovery time (tin) and finish time (tout)
21+
template<graph_type graph>
22+
struct dfs_time_range_context: dfs_time_context<graph> {
23+
using base = dfs_time_context<graph>;
24+
big_vector<int> tout;
25+
26+
dfs_time_range_context(graph const& g): base(g), tout(g.n()) {}
27+
28+
void on_exit(node_index v) {
29+
tout[v] = base::timer;
30+
}
31+
};
32+
33+
// Context that maintains tin and low (for Tarjan-like algorithms)
34+
template<graph_type graph>
35+
struct dfs_low_context: dfs_time_context<graph> {
36+
using base = dfs_time_context<graph>;
37+
big_vector<int> low;
38+
39+
dfs_low_context(graph const& g): base(g), low(g.n()) {}
40+
41+
void on_enter(node_index v) {
42+
base::on_enter(v);
43+
low[v] = base::tin[v];
44+
}
45+
46+
void on_return_from_child(node_index v, edge_index e) {
47+
node_index u = base::g->edge(e).traverse(v);
48+
low[v] = std::min(low[v], low[u]);
49+
}
50+
51+
void on_back_edge(node_index v, edge_index e) {
52+
node_index u = base::g->edge(e).traverse(v);
53+
low[v] = std::min(low[v], base::tin[u]);
54+
}
55+
56+
void on_forward_cross_edge(node_index v, edge_index e) {
57+
node_index u = base::g->edge(e).traverse(v);
58+
low[v] = std::min(low[v], base::tin[u]);
59+
}
60+
};
61+
}
62+
#endif // CP_ALGO_GRAPH_DFS_TIME_HPP

cp-algo/graph/tarjan.hpp

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,28 @@
11
#ifndef CP_ALGO_GRAPH_TARJAN_HPP
22
#define CP_ALGO_GRAPH_TARJAN_HPP
3-
#include "dfs.hpp"
3+
#include "dfs_time.hpp"
44
#include "base.hpp"
55
#include "../structures/csr.hpp"
66
#include <algorithm>
77
#include <cassert>
88
#include <stack>
99
namespace cp_algo::graph {
10+
// Add stack and components collection
1011
template<graph_type graph>
11-
struct tarjan_context: dfs_context<graph> {
12-
using base = dfs_context<graph>;
13-
big_vector<int> tin, low;
12+
struct tarjan_context: dfs_low_context<graph> {
13+
using base = dfs_low_context<graph>;
1414
std::stack<int> stack;
15-
int timer;
1615
structures::csr<node_index> components;
1716

18-
tarjan_context(graph const& g): base(g),
19-
tin(g.n()), low(g.n()), timer(0) {
17+
tarjan_context(graph const& g): base(g) {
2018
components.reserve_data(g.n());
2119
}
2220

2321
void on_enter(node_index v) {
24-
tin[v] = low[v] = timer++;
22+
base::on_enter(v);
2523
stack.push(v);
2624
}
2725

28-
void on_return_from_child(node_index v, edge_index e) {
29-
node_index u = base::g->edge(e).traverse(v);
30-
low[v] = std::min(low[v], low[u]);
31-
}
32-
33-
void on_back_edge(node_index v, edge_index e) {
34-
node_index u = base::g->edge(e).traverse(v);
35-
low[v] = std::min(low[v], tin[u]);
36-
}
37-
38-
void on_forward_cross_edge(node_index v, edge_index e) {
39-
node_index u = base::g->edge(e).traverse(v);
40-
low[v] = std::min(low[v], tin[u]);
41-
}
42-
43-
void on_tree_edge_processed(node_index, node_index, edge_index) {}
44-
4526
void collect(node_index v) {
4627
components.new_row();
4728
node_index u;

0 commit comments

Comments
 (0)