Skip to content

Commit 19e973d

Browse files
committed
feat: Refactor StrongConnectedComponents and TwoEdgeConnectedComponents implementations
1 parent 1da2c6c commit 19e973d

File tree

1 file changed

+33
-33
lines changed

1 file changed

+33
-33
lines changed

weilycoder/graph/tarjan.hpp

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,96 +8,96 @@
88
#include <vector>
99

1010
namespace weilycoder {
11-
template <typename ptr_t = size_t> struct TwoEdgeConnectedComponents {
12-
ptr_t dfs_time = 0, edge_time = 1;
11+
template <typename ptr_t = size_t> struct StrongConnectedComponents {
12+
ptr_t dfs_time = 0;
1313

1414
std::vector<bool> in_stack;
1515
std::stack<ptr_t> stk;
1616
std::vector<ptr_t> dfn, low;
17-
std::vector<std::vector<std::pair<ptr_t, ptr_t>>> graph;
17+
std::vector<std::vector<ptr_t>> graph;
1818

19-
std::vector<std::vector<ptr_t>> eccs;
19+
std::vector<std::vector<ptr_t>> sccs;
2020

21-
TwoEdgeConnectedComponents(ptr_t n)
21+
StrongConnectedComponents(ptr_t n)
2222
: in_stack(n, false), dfn(n, 0), low(n, 0), graph(n) {}
2323

24-
void add_edge(ptr_t u, ptr_t v) {
25-
graph[u].emplace_back(v, edge_time);
26-
graph[v].emplace_back(u, edge_time);
27-
edge_time++;
28-
}
24+
void add_edge(ptr_t u, ptr_t v) { graph[u].push_back(v); }
2925

30-
void tarjan(ptr_t u, ptr_t parent_edge) {
26+
void tarjan(ptr_t u) {
3127
dfn[u] = low[u] = ++dfs_time;
3228
stk.push(u), in_stack[u] = true;
3329

34-
for (const auto &[v, edge_id] : graph[u]) {
35-
if (edge_id == parent_edge)
36-
continue;
30+
for (const auto &v : graph[u]) {
3731
if (!dfn[v])
38-
tarjan(v, edge_id), low[u] = std::min(low[u], low[v]);
32+
tarjan(v), low[u] = std::min(low[u], low[v]);
3933
else if (in_stack[v])
4034
low[u] = std::min(low[u], dfn[v]);
4135
}
4236

4337
if (dfn[u] == low[u]) {
44-
eccs.emplace_back();
45-
eccs.back().push_back(u);
38+
sccs.emplace_back();
39+
sccs.back().push_back(u);
4640
in_stack[u] = false;
4741
while (stk.top() != u)
48-
eccs.back().push_back(stk.top()), in_stack[stk.top()] = false, stk.pop();
42+
sccs.back().push_back(stk.top()), in_stack[stk.top()] = false, stk.pop();
4943
stk.pop();
5044
}
5145
}
5246

5347
void solve() {
5448
for (size_t i = 0; i < graph.size(); ++i)
5549
if (!dfn[i])
56-
tarjan(i, 0);
50+
tarjan(i);
51+
std::reverse(sccs.begin(), sccs.end());
5752
}
5853
};
5954

60-
template <typename ptr_t = size_t> struct StrongConnectedComponents {
61-
ptr_t dfs_time = 0;
55+
template <typename ptr_t = size_t> struct TwoEdgeConnectedComponents {
56+
ptr_t dfs_time = 0, edge_time = 1;
6257

6358
std::vector<bool> in_stack;
6459
std::stack<ptr_t> stk;
6560
std::vector<ptr_t> dfn, low;
66-
std::vector<std::vector<ptr_t>> graph;
61+
std::vector<std::vector<std::pair<ptr_t, ptr_t>>> graph;
6762

68-
std::vector<std::vector<ptr_t>> sccs;
63+
std::vector<std::vector<ptr_t>> eccs;
6964

70-
StrongConnectedComponents(ptr_t n)
65+
TwoEdgeConnectedComponents(ptr_t n)
7166
: in_stack(n, false), dfn(n, 0), low(n, 0), graph(n) {}
7267

73-
void add_edge(ptr_t u, ptr_t v) { graph[u].push_back(v); }
68+
void add_edge(ptr_t u, ptr_t v) {
69+
graph[u].emplace_back(v, edge_time);
70+
graph[v].emplace_back(u, edge_time);
71+
edge_time++;
72+
}
7473

75-
void tarjan(ptr_t u) {
74+
void tarjan(ptr_t u, ptr_t parent_edge) {
7675
dfn[u] = low[u] = ++dfs_time;
7776
stk.push(u), in_stack[u] = true;
7877

79-
for (const auto &v : graph[u]) {
78+
for (const auto &[v, edge_id] : graph[u]) {
79+
if (edge_id == parent_edge)
80+
continue;
8081
if (!dfn[v])
81-
tarjan(v), low[u] = std::min(low[u], low[v]);
82+
tarjan(v, edge_id), low[u] = std::min(low[u], low[v]);
8283
else if (in_stack[v])
8384
low[u] = std::min(low[u], dfn[v]);
8485
}
8586

8687
if (dfn[u] == low[u]) {
87-
sccs.emplace_back();
88-
sccs.back().push_back(u);
88+
eccs.emplace_back();
89+
eccs.back().push_back(u);
8990
in_stack[u] = false;
9091
while (stk.top() != u)
91-
sccs.back().push_back(stk.top()), in_stack[stk.top()] = false, stk.pop();
92+
eccs.back().push_back(stk.top()), in_stack[stk.top()] = false, stk.pop();
9293
stk.pop();
9394
}
9495
}
9596

9697
void solve() {
9798
for (size_t i = 0; i < graph.size(); ++i)
9899
if (!dfn[i])
99-
tarjan(i);
100-
std::reverse(sccs.begin(), sccs.end());
100+
tarjan(i, 0);
101101
}
102102
};
103103

0 commit comments

Comments
 (0)