diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 0ed1f01f..f3e6e7a1 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -49,19 +49,18 @@ "tests/library_checker_aizu_tests/flow/dinic_lib_checker.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/flow/hungarian.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/flow/min_cost_max_flow.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/graphs/biconnected_components.test.cpp": "2024-12-14 19:50:29 -0600", +"tests/library_checker_aizu_tests/graphs/biconnected_components.test.cpp": "2024-12-15 08:00:27 -0600", "tests/library_checker_aizu_tests/graphs/connected_components_of_complement_graph.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/graphs/dijkstra_aizu.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/graphs/dijkstra_lib_checker.test.cpp": "2024-12-14 19:50:29 -0600", -"tests/library_checker_aizu_tests/graphs/directed_cycle.test.cpp": "2024-12-15 06:41:10 -0600", "tests/library_checker_aizu_tests/graphs/enumerate_triangles.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/graphs/hopcroft_karp_aizu.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/graphs/hopcroft_karp_lib_checker.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/graphs/mst.test.cpp": "2024-11-17 14:04:03 -0600", -"tests/library_checker_aizu_tests/graphs/offline_incremental_scc.test.cpp": "2024-12-14 19:50:29 -0600", -"tests/library_checker_aizu_tests/graphs/strongly_connected_components_aizu.test.cpp": "2024-12-14 19:50:29 -0600", -"tests/library_checker_aizu_tests/graphs/strongly_connected_components_lib_checker.test.cpp": "2024-12-14 19:50:29 -0600", -"tests/library_checker_aizu_tests/graphs/two_edge_components.test.cpp": "2024-12-14 19:50:29 -0600", +"tests/library_checker_aizu_tests/graphs/offline_incremental_scc.test.cpp": "2024-12-15 08:00:27 -0600", +"tests/library_checker_aizu_tests/graphs/strongly_connected_components_aizu.test.cpp": "2024-12-15 08:00:27 -0600", +"tests/library_checker_aizu_tests/graphs/strongly_connected_components_lib_checker.test.cpp": "2024-12-15 08:00:27 -0600", +"tests/library_checker_aizu_tests/graphs/two_edge_components.test.cpp": "2024-12-15 08:00:27 -0600", "tests/library_checker_aizu_tests/handmade_tests/count_paths_forest.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/handmade_tests/dsu_size.test.cpp": "2024-12-14 19:50:29 -0600", "tests/library_checker_aizu_tests/handmade_tests/dynamic_bitset.test.cpp": "2024-11-22 10:47:44 -0600", diff --git a/library/graphs/bridges_cuts/bridges.hpp b/library/graphs/bridges_cuts/bridges.hpp index e9c90866..dfed7d03 100644 --- a/library/graphs/bridges_cuts/bridges.hpp +++ b/library/graphs/bridges_cuts/bridges.hpp @@ -20,18 +20,17 @@ //! @time O(n + m) //! @space O(n + m) auto bridges(const auto& adj, int m) { - int n = sz(adj), num_ccs = 0, timer = 0; - vi br_id(n, -1), is_br(m), tin(n), st; - auto dfs = [&](auto&& self, int v, int p_id) -> int { - int low = tin[v] = ++timer, siz = sz(st); - st.push_back(v); - for (auto [u, e_id] : adj[v]) - if (e_id != p_id && br_id[u] < 0) - low = min(low, tin[u] ?: self(self, u, e_id)); + int n = sz(adj), num_ccs = 0, q = 0, s = 0; + vi br_id(n, -1), is_br(m), tin(n), st(n); + auto dfs = [&](auto&& self, int v, int p) -> int { + int low = tin[v] = ++q; + st[s++] = v; + for (auto [u, e] : adj[v]) + if (e != p && br_id[u] < 0) + low = min(low, tin[u] ?: self(self, u, e)); if (tin[v] == low) { - if (p_id != -1) is_br[p_id] = 1; - rep(i, siz, sz(st)) br_id[st[i]] = num_ccs; - st.resize(siz); + if (p != -1) is_br[p] = 1; + while (br_id[v] < 0) br_id[st[--s]] = num_ccs; num_ccs++; } return low; diff --git a/library/graphs/bridges_cuts/cuts.hpp b/library/graphs/bridges_cuts/cuts.hpp index d0ea0f4c..8aa7df2c 100644 --- a/library/graphs/bridges_cuts/cuts.hpp +++ b/library/graphs/bridges_cuts/cuts.hpp @@ -21,31 +21,22 @@ //! @time O(n + m) //! @space O(n + m) auto cuts(const auto& adj, int m) { - int n = sz(adj), num_bccs = 0, timer = 0; - vi bcc_id(m, -1), is_cut(n), tin(n), st; - auto dfs = [&](auto&& self, int v, int p_id) -> int { - int low = tin[v] = ++timer, deg = 0; - for (auto [u, e_id] : adj[v]) { + int n = sz(adj), num_bccs = 0, q = 0, s = 0; + vi bcc_id(m, -1), is_cut(n), tin(n), st(m); + auto dfs = [&](auto&& self, int v, int p) -> int { + int low = tin[v] = ++q; + for (auto [u, e] : adj[v]) { assert(v != u); - if (e_id == p_id) continue; - if (!tin[u]) { - int siz = sz(st); - st.push_back(e_id); - int low_ch = self(self, u, e_id); - if (low_ch >= tin[v]) { - is_cut[v] = 1; - rep(i, siz, sz(st)) bcc_id[st[i]] = num_bccs; - st.resize(siz); - num_bccs++; - } - low = min(low, low_ch); - deg++; - } else if (tin[u] < tin[v]) { - st.push_back(e_id); - low = min(low, tin[u]); + if (e == p) continue; + if (tin[u] < tin[v]) st[s++] = e; + int lu = -1; + low = min(low, tin[u] ?: (lu = self(self, u, e))); + if (lu >= tin[v]) { + is_cut[v] = p >= 0 || tin[v] + 1 < tin[u]; + while (bcc_id[e] < 0) bcc_id[st[--s]] = num_bccs; + num_bccs++; } } - if (p_id == -1) is_cut[v] = (deg > 1); return low; }; rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1); diff --git a/library/graphs/strongly_connected_components/scc.hpp b/library/graphs/strongly_connected_components/scc.hpp index 90fbc8ce..665cbc6e 100644 --- a/library/graphs/strongly_connected_components/scc.hpp +++ b/library/graphs/strongly_connected_components/scc.hpp @@ -13,17 +13,16 @@ //! @time O(n + m) //! @space O(n) auto sccs(const auto& adj) { - int n = sz(adj), num_sccs = 0, timer = 0; - vi scc_id(n, -1), tin(n), st; + int n = sz(adj), num_sccs = 0, q = 0, s = 0; + vi scc_id(n, -1), tin(n), st(n); auto dfs = [&](auto&& self, int v) -> int { - int low = tin[v] = ++timer, siz = sz(st); - st.push_back(v); + int low = tin[v] = ++q; + st[s++] = v; for (int u : adj[v]) if (scc_id[u] < 0) low = min(low, tin[u] ?: self(self, u)); if (tin[v] == low) { - rep(i, siz, sz(st)) scc_id[st[i]] = num_sccs; - st.resize(siz); + while (scc_id[v] < 0) scc_id[st[--s]] = num_sccs; num_sccs++; } return low;