Skip to content

Commit 3d5f5e1

Browse files
authored
[auto-verifier] docs commit 8a34dad
1 parent c3b53df commit 3d5f5e1

16 files changed

+1505
-673
lines changed

index.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,28 @@ data:
33
libraryCategories:
44
- name: weilycoder/ds
55
pages:
6+
- icon: ':heavy_check_mark:'
7+
path: weilycoder/ds/group.hpp
8+
title: Group Definitions
9+
- icon: ':heavy_check_mark:'
10+
path: weilycoder/ds/point_add_range_sum.hpp
11+
title: Point Add Range Sum using Fenwick Tree
612
- icon: ':heavy_check_mark:'
713
path: weilycoder/ds/static_range_sum.hpp
8-
title: weilycoder/ds/static_range_sum.hpp
14+
title: Static Range Sum using Prefix Sums
915
- icon: ':heavy_check_mark:'
1016
path: weilycoder/ds/unionfind.hpp
11-
title: weilycoder/ds/unionfind.hpp
17+
title: Union-Find (Disjoint Set Union) Data Structure
1218
- name: weilycoder
1319
pages:
1420
- icon: ':heavy_check_mark:'
1521
path: weilycoder/fast-io.hpp
16-
title: weilycoder/fast-io.hpp
22+
title: Fast Input/Output Utilities
1723
- name: weilycoder/graph
1824
pages:
1925
- icon: ':heavy_check_mark:'
2026
path: weilycoder/graph/tarjan.hpp
21-
title: weilycoder/graph/tarjan.hpp
27+
title: Tarjan's Algorithm for Graph Connected Problems
2228
verificationCategories:
2329
- name: test
2430
pages:
@@ -34,6 +40,9 @@ data:
3440
- icon: ':heavy_check_mark:'
3541
path: test/many_aplusb_128bit.test.cpp
3642
title: test/many_aplusb_128bit.test.cpp
43+
- icon: ':heavy_check_mark:'
44+
path: test/point_add_range_sum.test.cpp
45+
title: test/point_add_range_sum.test.cpp
3746
- icon: ':heavy_check_mark:'
3847
path: test/static_range_sum.test.cpp
3948
title: test/static_range_sum.test.cpp

test/aplusb.test.cpp.md

Lines changed: 133 additions & 73 deletions
Large diffs are not rendered by default.

test/biconnected_components.test.cpp.md

Lines changed: 73 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ data:
33
_extendedDependsOn:
44
- icon: ':heavy_check_mark:'
55
path: weilycoder/graph/tarjan.hpp
6-
title: weilycoder/graph/tarjan.hpp
6+
title: Tarjan's Algorithm for Graph Connected Problems
77
_extendedRequiredBy: []
88
_extendedVerifiedWith: []
99
_isVerificationFailed: false
@@ -16,64 +16,88 @@ data:
1616
- https://judge.yosupo.jp/problem/biconnected_components
1717
bundledCode: "#line 1 \"test/biconnected_components.test.cpp\"\n#define PROBLEM\
1818
\ \"https://judge.yosupo.jp/problem/biconnected_components\"\n\n#line 1 \"weilycoder/graph/tarjan.hpp\"\
19-
\n\n\n\n#include <algorithm>\n#include <cstddef>\n#include <stack>\n#include <utility>\n\
20-
#include <vector>\n\nnamespace weilycoder {\ntemplate <typename ptr_t = size_t>\
21-
\ struct StrongConnectedComponents {\n ptr_t dfs_time = 0;\n\n std::vector<bool>\
19+
\n\n\n\n/**\n * @file tarjan.hpp\n * @brief Tarjan's Algorithm for Graph Connected\
20+
\ Problems\n */\n\n#include <algorithm>\n#include <cstddef>\n#include <stack>\n\
21+
#include <utility>\n#include <vector>\n\nnamespace weilycoder {\n/**\n * @brief\
22+
\ Strongly Connected Components using Tarjan's Algorithm\n * @tparam ptr_t Type\
23+
\ for representing indices (default: size_t)\n */\ntemplate <typename ptr_t =\
24+
\ size_t> struct StrongConnectedComponents {\n ptr_t dfs_time = 0;\n\n std::vector<bool>\
2225
\ 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\
24-
\ n)\n : in_stack(n, false), dfn(n, 0), low(n, 0), graph(n) {}\n\n void\
25-
\ add_edge(ptr_t u, ptr_t v) { graph[u].push_back(v); }\n\n void tarjan(ptr_t\
26+
\ graph;\n\n std::vector<std::vector<ptr_t>> sccs;\n\n /**\n * @brief Constructs\
27+
\ a StrongConnectedComponents for n nodes\n * @param n Number of nodes\n */\n\
28+
\ StrongConnectedComponents(ptr_t n)\n : in_stack(n, false), dfn(n, 0),\
29+
\ low(n, 0), graph(n) {}\n\n /**\n * @brief Adds a directed edge from u to\
30+
\ v\n * @param u Source node\n * @param v Destination node\n */\n void\
31+
\ add_edge(ptr_t u, ptr_t v) { graph[u].push_back(v); }\n\n /**\n * @brief\
32+
\ Tarjan's DFS to find SCCs\n * @param u Current node\n */\n void tarjan(ptr_t\
2633
\ u) {\n dfn[u] = low[u] = ++dfs_time;\n stk.push(u), in_stack[u] = true;\n\
2734
\n for (const auto &v : graph[u]) {\n if (!dfn[v])\n tarjan(v),\
2835
\ low[u] = std::min(low[u], low[v]);\n else if (in_stack[v])\n low[u]\
2936
\ = std::min(low[u], dfn[v]);\n }\n\n if (dfn[u] == low[u]) {\n sccs.emplace_back();\n\
3037
\ sccs.back().push_back(u);\n in_stack[u] = false;\n while (stk.top()\
3138
\ != u)\n sccs.back().push_back(stk.top()), in_stack[stk.top()] = false,\n\
3239
\ stk.pop();\n stk.pop();\n }\n\
33-
\ }\n\n void solve() {\n for (size_t i = 0; i < graph.size(); ++i)\n \
34-
\ if (!dfn[i])\n tarjan(i);\n std::reverse(sccs.begin(), sccs.end());\n\
35-
\ }\n};\n\ntemplate <typename ptr_t = size_t> struct TwoEdgeConnectedComponents\
40+
\ }\n\n /**\n * @brief Solves for all SCCs in the graph, sorting them in DFS\
41+
\ order,\n * i.e., if there is an edge from SCC A to SCC B, then A appears\
42+
\ before B\n */\n void solve() {\n for (size_t i = 0; i < graph.size();\
43+
\ ++i)\n if (!dfn[i])\n tarjan(i);\n std::reverse(sccs.begin(),\
44+
\ sccs.end());\n }\n};\n\n/**\n * @brief Two-Edge Connected Components using\
45+
\ Tarjan's Algorithm\n * @tparam ptr_t Type for representing indices (default:\
46+
\ size_t)\n */\ntemplate <typename ptr_t = size_t> struct TwoEdgeConnectedComponents\
3647
\ {\n ptr_t dfs_time = 0, edge_time = 1;\n\n std::vector<bool> in_stack;\n \
3748
\ std::stack<ptr_t> stk;\n std::vector<ptr_t> dfn, low;\n std::vector<std::vector<std::pair<ptr_t,\
38-
\ ptr_t>>> graph;\n\n std::vector<std::vector<ptr_t>> eccs;\n\n TwoEdgeConnectedComponents(ptr_t\
39-
\ n)\n : in_stack(n, false), dfn(n, 0), low(n, 0), graph(n) {}\n\n void\
40-
\ add_edge(ptr_t u, ptr_t v) {\n graph[u].emplace_back(v, edge_time);\n \
41-
\ graph[v].emplace_back(u, edge_time);\n edge_time++;\n }\n\n void tarjan(ptr_t\
42-
\ u, ptr_t parent_edge) {\n dfn[u] = low[u] = ++dfs_time;\n stk.push(u),\
43-
\ in_stack[u] = true;\n\n for (const auto &[v, edge_id] : graph[u]) {\n \
44-
\ if (edge_id == parent_edge)\n continue;\n if (!dfn[v])\n \
45-
\ tarjan(v, edge_id), low[u] = std::min(low[u], low[v]);\n else if (in_stack[v])\n\
46-
\ low[u] = std::min(low[u], dfn[v]);\n }\n\n if (dfn[u] == low[u])\
47-
\ {\n eccs.emplace_back();\n eccs.back().push_back(u);\n in_stack[u]\
48-
\ = false;\n while (stk.top() != u)\n eccs.back().push_back(stk.top()),\
49+
\ ptr_t>>> graph;\n\n std::vector<std::vector<ptr_t>> eccs;\n\n /**\n * @brief\
50+
\ Constructs a TwoEdgeConnectedComponents for n nodes\n * @param n Number of\
51+
\ nodes\n */\n TwoEdgeConnectedComponents(ptr_t n)\n : in_stack(n, false),\
52+
\ dfn(n, 0), low(n, 0), graph(n) {}\n\n /**\n * @brief Adds an undirected edge\
53+
\ between u and v\n * @param u One endpoint\n * @param v Other endpoint\n\
54+
\ */\n void add_edge(ptr_t u, ptr_t v) {\n graph[u].emplace_back(v, edge_time);\n\
55+
\ graph[v].emplace_back(u, edge_time);\n edge_time++;\n }\n\n /**\n \
56+
\ * @brief Tarjan's DFS to find 2-edge connected components\n * @param u Current\
57+
\ node\n * @param parent_edge Edge ID of the edge leading to u\n */\n void\
58+
\ tarjan(ptr_t u, ptr_t parent_edge) {\n dfn[u] = low[u] = ++dfs_time;\n \
59+
\ stk.push(u), in_stack[u] = true;\n\n for (const auto &[v, edge_id] : graph[u])\
60+
\ {\n if (edge_id == parent_edge)\n continue;\n if (!dfn[v])\n\
61+
\ tarjan(v, edge_id), low[u] = std::min(low[u], low[v]);\n else if\
62+
\ (in_stack[v])\n low[u] = std::min(low[u], dfn[v]);\n }\n\n if (dfn[u]\
63+
\ == low[u]) {\n eccs.emplace_back();\n eccs.back().push_back(u);\n\
64+
\ in_stack[u] = false;\n while (stk.top() != u)\n eccs.back().push_back(stk.top()),\
4965
\ in_stack[stk.top()] = false,\n stk.pop();\n\
50-
\ stk.pop();\n }\n }\n\n void solve() {\n for (size_t i = 0; i <\
51-
\ graph.size(); ++i)\n if (!dfn[i])\n tarjan(i, 0);\n }\n};\n\ntemplate\
52-
\ <typename ptr_t = size_t> struct BiconnectedComponents {\n ptr_t dfs_time =\
53-
\ 0;\n\n std::stack<ptr_t> stk;\n std::vector<ptr_t> dfn, low;\n std::vector<std::vector<ptr_t>>\
54-
\ graph;\n\n std::vector<bool> is_cut;\n std::vector<std::vector<ptr_t>> dccs;\n\
55-
\n BiconnectedComponents(ptr_t n)\n : dfn(n, 0), low(n, 0), graph(n), is_cut(n,\
56-
\ false) {}\n\n void add_edge(ptr_t u, ptr_t v) {\n graph[u].push_back(v);\n\
57-
\ graph[v].push_back(u);\n }\n\n void tarjan(ptr_t u, bool is_root) {\n \
58-
\ dfn[u] = low[u] = ++dfs_time, stk.push(u);\n\n if (is_root && graph[u].empty())\
59-
\ {\n dccs.emplace_back();\n dccs.back().push_back(u);\n return;\n\
60-
\ }\n\n ptr_t child = 0;\n for (const auto &v : graph[u]) {\n if\
61-
\ (!dfn[v]) {\n tarjan(v, false), low[u] = std::min(low[u], low[v]);\n\
62-
\ if (low[v] >= dfn[u]) {\n if (++child > 1 || !is_root)\n \
63-
\ is_cut[u] = true;\n dccs.emplace_back();\n do\n \
64-
\ dccs.back().push_back(stk.top()), stk.pop();\n while (dccs.back().back()\
65-
\ != v);\n dccs.back().push_back(u);\n }\n } else\n \
66-
\ low[u] = std::min(low[u], dfn[v]);\n }\n }\n\n void solve() {\n for\
67-
\ (size_t i = 0; i < graph.size(); ++i)\n if (!dfn[i])\n tarjan(i,\
68-
\ true);\n }\n};\n} // namespace weilycoder\n\n\n#line 4 \"test/biconnected_components.test.cpp\"\
69-
\n#include <iostream>\nusing namespace std;\nusing namespace weilycoder;\n\nint\
70-
\ main() {\n cin.tie(nullptr)->sync_with_stdio(false);\n cin.exceptions(cin.failbit\
71-
\ | cin.badbit);\n size_t n, m;\n cin >> n >> m;\n\n BiconnectedComponents\
72-
\ graph(n);\n for (size_t i = 0; i < m; ++i) {\n size_t u, v;\n cin >>\
73-
\ u >> v;\n graph.add_edge(u, v);\n }\n\n graph.solve();\n\n cout << graph.dccs.size()\
74-
\ << '\\n';\n for (const auto &dcc : graph.dccs) {\n cout << dcc.size();\n\
75-
\ for (size_t u : dcc)\n cout << ' ' << u;\n cout << '\\n';\n }\n\
76-
\ return 0;\n}\n"
66+
\ stk.pop();\n }\n }\n\n /**\n * @brief Solves for all 2-edge connected\
67+
\ components in the graph\n */\n void solve() {\n for (size_t i = 0; i <\
68+
\ graph.size(); ++i)\n if (!dfn[i])\n tarjan(i, 0);\n }\n};\n\n/**\n\
69+
\ * @brief Biconnected Components using Tarjan's Algorithm\n * @tparam ptr_t Type\
70+
\ for representing indices (default: size_t)\n */\ntemplate <typename ptr_t =\
71+
\ size_t> struct BiconnectedComponents {\n ptr_t dfs_time = 0;\n\n std::stack<ptr_t>\
72+
\ stk;\n std::vector<ptr_t> dfn, low;\n std::vector<std::vector<ptr_t>> graph;\n\
73+
\n std::vector<bool> is_cut;\n std::vector<std::vector<ptr_t>> dccs;\n\n /**\n\
74+
\ * @brief Constructs a BiconnectedComponents for n nodes\n * @param n Number\
75+
\ of nodes\n */\n BiconnectedComponents(ptr_t n)\n : dfn(n, 0), low(n,\
76+
\ 0), graph(n), is_cut(n, false) {}\n\n /**\n * @brief Adds an undirected edge\
77+
\ between u and v\n * @param u One endpoint\n * @param v Other endpoint\n\
78+
\ */\n void add_edge(ptr_t u, ptr_t v) {\n graph[u].push_back(v);\n graph[v].push_back(u);\n\
79+
\ }\n\n /**\n * @brief Tarjan's DFS to find biconnected components\n * @param\
80+
\ u Current node\n * @param is_root Whether u is the root of the DFS tree\n\
81+
\ */\n void tarjan(ptr_t u, bool is_root) {\n dfn[u] = low[u] = ++dfs_time,\
82+
\ stk.push(u);\n\n if (is_root && graph[u].empty()) {\n dccs.emplace_back();\n\
83+
\ dccs.back().push_back(u);\n return;\n }\n\n ptr_t child = 0;\n\
84+
\ for (const auto &v : graph[u]) {\n if (!dfn[v]) {\n tarjan(v,\
85+
\ false), low[u] = std::min(low[u], low[v]);\n if (low[v] >= dfn[u]) {\n\
86+
\ if (++child > 1 || !is_root)\n is_cut[u] = true;\n \
87+
\ dccs.emplace_back();\n do\n dccs.back().push_back(stk.top()),\
88+
\ stk.pop();\n while (dccs.back().back() != v);\n dccs.back().push_back(u);\n\
89+
\ }\n } else\n low[u] = std::min(low[u], dfn[v]);\n }\n\
90+
\ }\n\n /**\n * @brief Solves for all biconnected components in the graph\n\
91+
\ */\n void solve() {\n for (size_t i = 0; i < graph.size(); ++i)\n \
92+
\ if (!dfn[i])\n tarjan(i, true);\n }\n};\n} // namespace weilycoder\n\
93+
\n\n#line 4 \"test/biconnected_components.test.cpp\"\n#include <iostream>\nusing\
94+
\ namespace std;\nusing namespace weilycoder;\n\nint main() {\n cin.tie(nullptr)->sync_with_stdio(false);\n\
95+
\ cin.exceptions(cin.failbit | cin.badbit);\n size_t n, m;\n cin >> n >> m;\n\
96+
\n BiconnectedComponents graph(n);\n for (size_t i = 0; i < m; ++i) {\n size_t\
97+
\ u, v;\n cin >> u >> v;\n graph.add_edge(u, v);\n }\n\n graph.solve();\n\
98+
\n cout << graph.dccs.size() << '\\n';\n for (const auto &dcc : graph.dccs)\
99+
\ {\n cout << dcc.size();\n for (size_t u : dcc)\n cout << ' ' << u;\n\
100+
\ cout << '\\n';\n }\n return 0;\n}\n"
77101
code: "#define PROBLEM \"https://judge.yosupo.jp/problem/biconnected_components\"\
78102
\n\n#include \"../weilycoder/graph/tarjan.hpp\"\n#include <iostream>\nusing namespace\
79103
\ std;\nusing namespace weilycoder;\n\nint main() {\n cin.tie(nullptr)->sync_with_stdio(false);\n\
@@ -88,7 +112,7 @@ data:
88112
isVerificationFile: true
89113
path: test/biconnected_components.test.cpp
90114
requiredBy: []
91-
timestamp: '2025-10-29 23:28:06+08:00'
115+
timestamp: '2025-10-30 21:08:13+08:00'
92116
verificationStatus: TEST_ACCEPTED
93117
verifiedWith: []
94118
documentation_of: test/biconnected_components.test.cpp

0 commit comments

Comments
 (0)