@@ -18,36 +18,52 @@ data:
1818 \ \" https://judge.yosupo.jp/problem/scc\"\n\n #line 1 \" weilycoder/graph/tarjan.hpp\" \
1919 \n\n\n\n #include <algorithm>\n #include <cstddef>\n #include <stack>\n #include <utility>\n \
2020 #include <vector>\n\n namespace weilycoder {\n template <typename ptr_t = size_t>\
21- \ struct TwoEdgeConnectedComponents {\n ptr_t dfs_time = 0, edge_time = 1;\n\n \
22- \ std::vector<bool> in_stack;\n std::stack<ptr_t> stk;\n std::vector<ptr_t>\
23- \ dfn, low;\n std::vector<std::vector<std::pair<ptr_t, ptr_t>>> graph;\n\n std::vector<std::vector<ptr_t>>\
24- \ eccs;\n\n TwoEdgeConnectedComponents(ptr_t n)\n : in_stack(n, false),\
25- \ dfn(n, 0), low(n, 0), graph(n) {}\n\n void add_edge(ptr_t u, ptr_t v) {\n \
26- \ graph[u].emplace_back(v, edge_time);\n graph[v].emplace_back(u, edge_time);\n \
27- \ edge_time++;\n }\n\n void tarjan(ptr_t u, ptr_t parent_edge) {\n dfn[u]\
28- \ = low[u] = ++dfs_time;\n stk.push(u);\n in_stack[u] = true;\n\n for\
29- \ (const auto &[v, edge_id] : graph[u]) {\n if (edge_id == parent_edge)\n \
30- \ continue;\n if (!dfn[v])\n tarjan(v, edge_id), low[u] = std::min(low[u],\
31- \ low[v]);\n else if (in_stack[v])\n low[u] = std::min(low[u], dfn[v]);\n \
32- \ }\n\n if (dfn[u] == low[u]) {\n eccs.emplace_back();\n eccs.back().push_back(u);\n \
33- \ in_stack[u] = false;\n while (stk.top() != u)\n eccs.back().push_back(stk.top()),\
34- \ in_stack[stk.top()] = false, stk.pop();\n stk.pop();\n }\n }\n\n void\
35- \ solve() {\n for (size_t i = 0; i < graph.size(); ++i)\n if (!dfn[i])\n \
36- \ tarjan(i, 0);\n }\n };\n\n template <typename ptr_t = size_t> struct StrongConnectedComponents\
37- \ {\n ptr_t dfs_time = 0;\n\n std::vector<bool> in_stack;\n std::stack<ptr_t>\
38- \ stk;\n std::vector<ptr_t> dfn, low;\n std::vector<std::vector<ptr_t>> graph;\n \
39- \n std::vector<std::vector<ptr_t>> sccs;\n\n StrongConnectedComponents(ptr_t\
21+ \ struct StrongConnectedComponents {\n ptr_t dfs_time = 0;\n\n std::vector<bool>\
22+ \ in_stack;\n std::stack<ptr_t> stk;\n std::vector<ptr_t> dfn, low;\n std::vector<std::vector<ptr_t>>\
23+ \ graph;\n\n std::vector<std::vector<ptr_t>> sccs;\n\n StrongConnectedComponents(ptr_t\
4024 \ n)\n : in_stack(n, false), dfn(n, 0), low(n, 0), graph(n) {}\n\n void\
4125 \ add_edge(ptr_t u, ptr_t v) { graph[u].push_back(v); }\n\n void tarjan(ptr_t\
42- \ u) {\n dfn[u] = low[u] = ++dfs_time;\n stk.push(u); \n in_stack[u] =\
43- \ true; \n\ n for (const auto &v : graph[u]) {\n if (!dfn[v])\n tarjan(v),\
26+ \ u) {\n dfn[u] = low[u] = ++dfs_time;\n stk.push(u), in_stack[u] = true; \n \
27+ \n for (const auto &v : graph[u]) {\n if (!dfn[v])\n tarjan(v),\
4428 \ low[u] = std::min(low[u], low[v]);\n else if (in_stack[v])\n low[u]\
4529 \ = std::min(low[u], dfn[v]);\n }\n\n if (dfn[u] == low[u]) {\n sccs.emplace_back();\n \
4630 \ sccs.back().push_back(u);\n in_stack[u] = false;\n while (stk.top()\
4731 \ != u)\n sccs.back().push_back(stk.top()), in_stack[stk.top()] = false,\
4832 \ stk.pop();\n stk.pop();\n }\n }\n\n void solve() {\n for (size_t\
4933 \ i = 0; i < graph.size(); ++i)\n if (!dfn[i])\n tarjan(i);\n std::reverse(sccs.begin(),\
50- \ sccs.end());\n }\n };\n } // namespace weilycoder\n\n\n #line 4 \" test/strongly_connected_components.test.cpp\" \
34+ \ sccs.end());\n }\n };\n\n template <typename ptr_t = size_t> struct TwoEdgeConnectedComponents\
35+ \ {\n ptr_t dfs_time = 0, edge_time = 1;\n\n std::vector<bool> in_stack;\n \
36+ \ std::stack<ptr_t> stk;\n std::vector<ptr_t> dfn, low;\n std::vector<std::vector<std::pair<ptr_t,\
37+ \ ptr_t>>> graph;\n\n std::vector<std::vector<ptr_t>> eccs;\n\n TwoEdgeConnectedComponents(ptr_t\
38+ \ n)\n : in_stack(n, false), dfn(n, 0), low(n, 0), graph(n) {}\n\n void\
39+ \ add_edge(ptr_t u, ptr_t v) {\n graph[u].emplace_back(v, edge_time);\n \
40+ \ graph[v].emplace_back(u, edge_time);\n edge_time++;\n }\n\n void tarjan(ptr_t\
41+ \ u, ptr_t parent_edge) {\n dfn[u] = low[u] = ++dfs_time;\n stk.push(u),\
42+ \ in_stack[u] = true;\n\n for (const auto &[v, edge_id] : graph[u]) {\n \
43+ \ if (edge_id == parent_edge)\n continue;\n if (!dfn[v])\n \
44+ \ tarjan(v, edge_id), low[u] = std::min(low[u], low[v]);\n else if (in_stack[v])\n \
45+ \ low[u] = std::min(low[u], dfn[v]);\n }\n\n if (dfn[u] == low[u])\
46+ \ {\n eccs.emplace_back();\n eccs.back().push_back(u);\n in_stack[u]\
47+ \ = false;\n while (stk.top() != u)\n eccs.back().push_back(stk.top()),\
48+ \ in_stack[stk.top()] = false, stk.pop();\n stk.pop();\n }\n }\n\n void\
49+ \ solve() {\n for (size_t i = 0; i < graph.size(); ++i)\n if (!dfn[i])\n \
50+ \ tarjan(i, 0);\n }\n };\n\n template <typename ptr_t = size_t> struct BiconnectedComponents\
51+ \ {\n ptr_t dfs_time = 0;\n\n std::stack<ptr_t> stk;\n std::vector<ptr_t> dfn,\
52+ \ low;\n std::vector<std::vector<ptr_t>> graph;\n\n std::vector<bool> is_cut;\n \
53+ \ std::vector<std::vector<ptr_t>> dccs;\n\n BiconnectedComponents(ptr_t n) :\
54+ \ dfn(n, 0), low(n, 0), graph(n), is_cut(n, false) {}\n\n void add_edge(ptr_t\
55+ \ u, ptr_t v) {\n graph[u].push_back(v);\n graph[v].push_back(u);\n }\n \
56+ \n void tarjan(ptr_t u, bool is_root) {\n dfn[u] = low[u] = ++dfs_time, stk.push(u);\n \
57+ \n if (is_root && graph[u].empty()) {\n dccs.emplace_back();\n dccs.back().push_back(u);\n \
58+ \ return;\n }\n\n ptr_t child = 0;\n for (const auto &v : graph[u])\
59+ \ {\n if (!dfn[v]) {\n tarjan(v, false), low[u] = std::min(low[u],\
60+ \ low[v]);\n if (low[v] >= dfn[u]) {\n if (++child > 1 || !is_root)\n \
61+ \ is_cut[u] = true;\n dccs.emplace_back();\n do\n \
62+ \ dccs.back().push_back(stk.top()), stk.pop();\n while (dccs.back().back()\
63+ \ != v);\n dccs.back().push_back(u);\n }\n } else\n \
64+ \ low[u] = std::min(low[u], dfn[v]);\n }\n }\n\n void solve() {\n for\
65+ \ (size_t i = 0; i < graph.size(); ++i)\n if (!dfn[i])\n tarjan(i,\
66+ \ true);\n }\n };\n } // namespace weilycoder\n\n\n #line 4 \" test/strongly_connected_components.test.cpp\" \
5167 \n #include <iostream>\n using namespace std;\n using namespace weilycoder;\n\n int\
5268 \ main() {\n cin.tie(nullptr)->sync_with_stdio(false);\n cin.exceptions(cin.failbit\
5369 \ | cin.badbit);\n size_t n, m;\n cin >> n >> m;\n\n StrongConnectedComponents\
7086 isVerificationFile : true
7187 path : test/strongly_connected_components.test.cpp
7288 requiredBy : []
73- timestamp : ' 2025-10-28 21:05:17 +08:00'
89+ timestamp : ' 2025-10-28 22:39:45 +08:00'
7490 verificationStatus : TEST_ACCEPTED
7591 verifiedWith : []
7692documentation_of : test/strongly_connected_components.test.cpp
0 commit comments