|
3 | 3 | //! @code |
4 | 4 | //! { |
5 | 5 | //! vector<vector<pii>> adj(n); |
6 | | -//! auto [num_bccs, is_cut, bcc_id] = cuts(adj, m); |
| 6 | +//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m); |
7 | 7 | //! } |
8 | 8 | //! vector<basic_string<array<int, 2>>> adj(n); |
9 | 9 | //! rep (i, 0, m) { |
|
14 | 14 | //! adj[u].push_back({v, i}); |
15 | 15 | //! adj[v].push_back({u, i}); |
16 | 16 | //! } |
17 | | -//! auto [num_bccs, is_cut, bcc_id] = cuts(adj, m); |
| 17 | +//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m); |
18 | 18 | //! @endcode |
19 | 19 | //! is_cut[v] = 1 iff cut node |
20 | 20 | //! bcc_id[edge id] = id, 0<=id<num_bccs |
21 | 21 | //! @time O(n + m) |
22 | 22 | //! @space O(n + m) |
23 | | -template<class G> struct cuts { |
24 | | - int num_bccs = 0; |
25 | | - vector<bool> is_cut; |
26 | | - vi bcc_id; |
27 | | - cuts(const G& adj, int m): |
28 | | - is_cut(sz(adj)), bcc_id(m, -1) { |
29 | | - int n = sz(adj), timer = 1; |
30 | | - vi tin(n), st; |
31 | | - auto dfs = [&](auto&& self, int v, int p_id) -> int { |
32 | | - int low = tin[v] = timer++, deg = 0; |
33 | | - for (auto [u, e_id] : adj[v]) { |
34 | | - assert(v != u); |
35 | | - if (e_id == p_id) continue; |
36 | | - if (!tin[u]) { |
37 | | - int siz = sz(st); |
38 | | - st.push_back(e_id); |
39 | | - int low_ch = self(self, u, e_id); |
40 | | - if (low_ch >= tin[v]) { |
41 | | - is_cut[v] = 1; |
42 | | - rep(i, siz, sz(st)) bcc_id[st[i]] = num_bccs; |
43 | | - st.resize(siz); |
44 | | - num_bccs++; |
45 | | - } |
46 | | - low = min(low, low_ch); |
47 | | - deg++; |
48 | | - } else if (tin[u] < tin[v]) { |
49 | | - st.push_back(e_id); |
50 | | - low = min(low, tin[u]); |
| 23 | +auto cuts(const auto& adj, int m) { |
| 24 | + int n = sz(adj), num_bccs = 0, timer = 0; |
| 25 | + vi bcc_id(m, -1), is_cut(n), tin(n), st; |
| 26 | + auto dfs = [&](auto&& self, int v, int p_id) -> int { |
| 27 | + int low = tin[v] = ++timer, deg = 0; |
| 28 | + for (auto [u, e_id] : adj[v]) { |
| 29 | + assert(v != u); |
| 30 | + if (e_id == p_id) continue; |
| 31 | + if (!tin[u]) { |
| 32 | + int siz = sz(st); |
| 33 | + st.push_back(e_id); |
| 34 | + int low_ch = self(self, u, e_id); |
| 35 | + if (low_ch >= tin[v]) { |
| 36 | + is_cut[v] = 1; |
| 37 | + rep(i, siz, sz(st)) bcc_id[st[i]] = num_bccs; |
| 38 | + st.resize(siz); |
| 39 | + num_bccs++; |
51 | 40 | } |
| 41 | + low = min(low, low_ch); |
| 42 | + deg++; |
| 43 | + } else if (tin[u] < tin[v]) { |
| 44 | + st.push_back(e_id); |
| 45 | + low = min(low, tin[u]); |
52 | 46 | } |
53 | | - if (p_id == -1) is_cut[v] = (deg > 1); |
54 | | - return low; |
55 | | - }; |
56 | | - rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1); |
57 | | - } |
58 | | -}; |
| 47 | + } |
| 48 | + if (p_id == -1) is_cut[v] = (deg > 1); |
| 49 | + return low; |
| 50 | + }; |
| 51 | + rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1); |
| 52 | + return tuple{num_bccs, bcc_id, is_cut}; |
| 53 | +} |
0 commit comments