|
| 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 |
0 commit comments