diff --git a/library/dsu/kruskal_tree.hpp b/library/dsu/kruskal_tree.hpp index f0d1f0bb3..e854110ca 100644 --- a/library/dsu/kruskal_tree.hpp +++ b/library/dsu/kruskal_tree.hpp @@ -5,11 +5,11 @@ struct kr_tree { int id; vi p; - vector adj; - kr_tree(int n): id(n), p(2 * n, -1), adj(2 * n) {} + vector g; + kr_tree(int n): id(n), p(2 * n, -1), g(2 * n) {} int f(int u) { return p[u] < 0 ? u : p[u] = f(p[u]); } bool join(int u, int v) { if ((u = f(u)) == (v = f(v))) return 0; - return adj[p[u] = p[v] = id++] = {u, v}, 1; + return g[p[u] = p[v] = id++] = {u, v}, 1; } }; diff --git a/library/flow/min_cost_max_flow.hpp b/library/flow/min_cost_max_flow.hpp index f2028a7f6..77bd253f3 100644 --- a/library/flow/min_cost_max_flow.hpp +++ b/library/flow/min_cost_max_flow.hpp @@ -17,14 +17,14 @@ struct mcmf { }; int n; vector e; - vector adj; - mcmf(int n): n(n), adj(n) {} + vector g; + mcmf(int n): n(n), g(n) {} void add_edge(int u, int v, ll cap, ll cost) { - edge e1 = {u, v, cap, cost, 0, sz(adj[v])}; - edge e2 = {v, u, 0, -cost, 0, sz(adj[u])}; - adj[u].push_back(sz(e)); + edge e1 = {u, v, cap, cost, 0, sz(g[v])}; + edge e2 = {v, u, 0, -cost, 0, sz(g[u])}; + g[u].push_back(sz(e)); e.push_back(e1); - adj[v].push_back(sz(e)); + g[v].push_back(sz(e)); e.push_back(e2); } array get_flow(int s, int t, ll total_flow) { @@ -39,8 +39,8 @@ struct mcmf { int u = q[qh++]; id[u] = 2; if (qh == n) qh = 0; - rep(i, 0, sz(adj[u])) { - edge& r = e[adj[u][i]]; + rep(i, 0, sz(g[u])) { + edge& r = e[g[u][i]]; if (r.flow < r.cap && d[u] + r.cost < d[r.v]) { d[r.v] = d[u] + r.cost; if (id[r.v] == 0) { @@ -61,14 +61,14 @@ struct mcmf { for (int u = t; u != s; u = p[u]) { int pv = p[u], pr = p_edge[u]; addflow = min(addflow, - e[adj[pv][pr]].cap - e[adj[pv][pr]].flow); + e[g[pv][pr]].cap - e[g[pv][pr]].flow); } for (int u = t; u != s; u = p[u]) { int pv = p[u], pr = p_edge[u], - r = e[adj[pv][pr]].back; - e[adj[pv][pr]].flow += addflow; - e[adj[u][r]].flow -= addflow; - cost += e[adj[pv][pr]].cost * addflow; + r = e[g[pv][pr]].back; + e[g[pv][pr]].flow += addflow; + e[g[u][r]].flow -= addflow; + cost += e[g[pv][pr]].cost * addflow; } flow += addflow; } diff --git a/library/graphs/bcc_callback.hpp b/library/graphs/bcc_callback.hpp index 38a3babac..268bdd808 100644 --- a/library/graphs/bcc_callback.hpp +++ b/library/graphs/bcc_callback.hpp @@ -2,14 +2,14 @@ //! https://cp-algorithms.com/graph/cutpoints.html //! @code //! { -//! vector adj(n); +//! vector g(n); //! DSU dsu(n); //! vector seen(n); -//! bcc(adj, [&](const vi& nodes) { +//! bcc(g, [&](const vi& nodes) { //! int count_edges = 0; //! rep (i, 0, sz(nodes) - 1) { //! seen[nodes[i]] = 1; -//! for (int u : adj[nodes[i]]) if (!seen[u]) { +//! for (int u : g[nodes[i]]) if (!seen[u]) { //! // edge nodes[i] <=> u is in current BCC //! count_edges++; //! } @@ -22,15 +22,15 @@ //! }); //! vector> bridge_tree(n); //! rep (i, 0, n) -//! for (int u : adj[i]) +//! for (int u : g[i]) //! if (dsu.f(i) != dsu.f(u)) //! bridge_tree[dsu.f(i)] += dsu.f(u); //! } //! -//! vector> adj(n); +//! vector> g(n); //! vector> block_vertex_tree(2 * n); //! int bcc_id = n; -//! bcc(adj, [&](const vi& nodes) { +//! bcc(g, [&](const vi& nodes) { //! for (int u : nodes) { //! block_vertex_tree[u] += bcc_id; //! block_vertex_tree[bcc_id] += u; @@ -41,12 +41,12 @@ //! callback not called on components with a single node //! @time O(n + m) //! @space O(n) -void bcc(const auto& adj, auto f) { - int n = sz(adj), q = 0, s = 0; +void bcc(const auto& g, auto f) { + int n = sz(g), q = 0, s = 0; vi t(n), st(n); auto dfs = [&](auto&& dfs, int u) -> int { int l = t[u] = ++q; - for (int v : adj[u]) { + for (int v : g[u]) { int siz = s, lu = 0; l = min(l, t[v] ?: (lu = dfs(dfs, st[s++] = v))); if (lu >= t[u]) { diff --git a/library/graphs/dijkstra.hpp b/library/graphs/dijkstra.hpp index c5c4ec40a..9d63b52bf 100644 --- a/library/graphs/dijkstra.hpp +++ b/library/graphs/dijkstra.hpp @@ -1,22 +1,22 @@ #pragma once //! @code -//! vector>> adj(n); -//! auto d = dijkstra(adj, source); +//! vector>> g(n); +//! auto d = dijkstra(g, source); //! @endcode //! d[v] = min dist from source->..->v //! @time O(n + (m log m)) //! @space O(n + m) -vector dijkstra(const auto& adj, int s) { +vector dijkstra(const auto& g, int s) { using p = pair; priority_queue, greater<>> pq; pq.emplace(0, s); - vector d(sz(adj), LLONG_MAX); + vector d(sz(g), LLONG_MAX); while (!empty(pq)) { auto [d_v, v] = pq.top(); pq.pop(); if (d[v] != LLONG_MAX) continue; d[v] = d_v; - for (auto [u, w] : adj[v]) pq.emplace(w + d_v, u); + for (auto [u, w] : g[v]) pq.emplace(w + d_v, u); } return d; } diff --git a/library/graphs/euler_path.hpp b/library/graphs/euler_path.hpp index 3df239861..e0ab350f4 100644 --- a/library/graphs/euler_path.hpp +++ b/library/graphs/euler_path.hpp @@ -1,25 +1,25 @@ #pragma once //! @code -//! vector>> adj(n); +//! vector>> g(n); //! vector edges(m); //! rep(i, 0, m) { //! int u, v; //! cin >> u >> v; //! u--, v--; -//! adj[u] += {v, i}; +//! g[u] += {v, i}; //! edges[i] = {u, v}; //! } -//! vector path = euler_path(adj, m, source); +//! vector path = euler_path(g, m, source); //! @endcode //! @time O(n + m) //! @space O(n + m) -vector euler_path(auto& adj, int m, int s) { +vector euler_path(auto& g, int m, int s) { vi vis(m); vector path; auto dfs = [&](auto&& dfs, int u, int eu) -> void { - while (!empty(adj[u])) { - auto [v, ev] = adj[u].back(); - adj[u].pop_back(); + while (!empty(g[u])) { + auto [v, ev] = g[u].back(); + g[u].pop_back(); if (!vis[ev]) vis[ev] = 1, dfs(dfs, v, ev); } path.emplace_back(u, eu); diff --git a/library/graphs/hopcroft_karp.hpp b/library/graphs/hopcroft_karp.hpp index 60446ea6e..586def983 100644 --- a/library/graphs/hopcroft_karp.hpp +++ b/library/graphs/hopcroft_karp.hpp @@ -1,11 +1,11 @@ #pragma once //! https://github.com/foreverbell/acm-icpc-cheat-sheet/blob/master/src/graph-algorithm/hopcroft-karp.cpp //! @code -//! vector> adj(lsz); -//! adj[l] += r; // add edge l <-> r +//! vector> g(lsz); +//! g[l] += r; // add edge l <-> r //! // 0<=l to_r[l] in matching if to_r[l]!=-1 //! to_l[r] <-> r in matching if to_l[r]!=-1 @@ -17,9 +17,9 @@ struct hopcroft_karp { int m_sz = 0; vi to_r, to_l; vector mvc_l, mvc_r; - hopcroft_karp(const auto& adj, int rsz): - to_r(sz(adj), -1), to_l(rsz, -1) { - int lsz = sz(adj); + hopcroft_karp(const auto& g, int rsz): + to_r(sz(g), -1), to_l(rsz, -1) { + int lsz = sz(g); while (1) { queue q; vi level(lsz, -1); @@ -32,7 +32,7 @@ struct hopcroft_karp { int u = q.front(); q.pop(); mvc_l[u] = 0; - for (int v : adj[u]) { + for (int v : g[u]) { mvc_r[v] = 1; int w = to_l[v]; if (w == -1) found = 1; @@ -44,7 +44,7 @@ struct hopcroft_karp { } if (!found) break; auto dfs = [&](auto&& dfs, int u) -> bool { - for (int v : adj[u]) { + for (int v : g[u]) { int w = to_l[v]; if (w == -1 || (level[u] + 1 == level[w] && dfs(dfs, w))) { diff --git a/library/graphs/scc.hpp b/library/graphs/scc.hpp index 493f12137..fc2673cf1 100644 --- a/library/graphs/scc.hpp +++ b/library/graphs/scc.hpp @@ -1,20 +1,20 @@ #pragma once //! https://github.com/kth-competitive-programming/kactl/blob/main/content/graph/SCC.h //! @code -//! vector> adj(n); -//! auto [num_sccs, scc_id] = scc(adj); +//! vector> g(n); +//! auto [num_sccs, scc_id] = scc(g); //! @endcode //! scc_id[u] = id, 0<=id v: scc_id[u] >= scc_id[v] //! @time O(n + m) //! @space O(n) -auto scc(const auto& adj) { - int n = sz(adj), num_sccs = 0, q = 0, s = 0; +auto scc(const auto& g) { + int n = sz(g), num_sccs = 0, q = 0, s = 0; vi scc_id(n, -1), tin(n), st(n); auto dfs = [&](auto&& dfs, int u) -> int { int low = tin[u] = ++q; st[s++] = u; - for (int v : adj[u]) + for (int v : g[u]) if (scc_id[v] < 0) low = min(low, tin[v] ?: dfs(dfs, v)); if (tin[u] == low) { diff --git a/library/graphs/strongly_connected_components/add_edges_strongly_connected.hpp b/library/graphs/strongly_connected_components/add_edges_strongly_connected.hpp index 9247aea09..01dc54b6b 100644 --- a/library/graphs/strongly_connected_components/add_edges_strongly_connected.hpp +++ b/library/graphs/strongly_connected_components/add_edges_strongly_connected.hpp @@ -8,30 +8,30 @@ //! SCCs) //! //! @code -//! auto [num_sccs, scc_id] = scc(adj); -//! vector edges = extra_edges(adj, +//! auto [num_sccs, scc_id] = scc(g); +//! vector edges = extra_edges(g, //! num_sccs, scc_id); //! @endcode -//! @param adj,num_sccs,scc_id directed graph and its SCCs +//! @param g,num_sccs,scc_id directed graph and its SCCs //! @returns directed edge list: edges[i][0] -> edges[i][1] //! @time O(n + m) //! @space An O(n) edge list is allocated and returned, but //! multiple O(n + m) vectors are allocated temporarily -vector extra_edges(const auto& adj, int num_sccs, +vector extra_edges(const auto& g, int num_sccs, const vi& scc_id) { if (num_sccs == 1) return {}; - int n = sz(adj); - vector scc_adj(num_sccs); + int n = sz(g); + vector scc_g(num_sccs); vector zero_in(num_sccs, 1); - rep(i, 0, n) for (int v : adj[i]) { + rep(i, 0, n) for (int v : g[i]) { if (scc_id[i] == scc_id[v]) continue; - scc_adj[scc_id[i]].push_back(scc_id[v]); + scc_g[scc_id[i]].push_back(scc_id[v]); zero_in[scc_id[v]] = 0; } vector vis(num_sccs); auto dfs = [&](auto&& dfs, int u) { - if (empty(scc_adj[u])) return u; - for (int v : scc_adj[u]) + if (empty(scc_g[u])) return u; + for (int v : scc_g[u]) if (!vis[v]) { vis[v] = 1; int zero_out = dfs(dfs, v); @@ -49,7 +49,7 @@ vector extra_edges(const auto& adj, int num_sccs, } rep(i, 1, sz(edges)) swap(edges[i].first, edges[i - 1].first); - rep(i, 0, num_sccs) if (empty(scc_adj[i]) && !vis[i]) { + rep(i, 0, num_sccs) if (empty(scc_g[i]) && !vis[i]) { if (!empty(in_unused)) { edges.emplace_back(i, in_unused.back()); in_unused.pop_back(); diff --git a/library/graphs/strongly_connected_components/offline_incremental_scc.hpp b/library/graphs/strongly_connected_components/offline_incremental_scc.hpp index c977a0d39..ae03effed 100644 --- a/library/graphs/strongly_connected_components/offline_incremental_scc.hpp +++ b/library/graphs/strongly_connected_components/offline_incremental_scc.hpp @@ -15,24 +15,24 @@ vi offline_incremental_scc(vector> eds, int m = sz(eds); vi ids(n, -1), joins(m, m), idx(m), vs(n), scc_id; iota(all(idx), 0); - vector adj; + vector g; auto dnc = [&](auto&& dnc, auto el, auto er, int tl, int tr) { - adj.clear(); + g.clear(); int mid = midpoint(tl, tr); for (auto it = el; it != er; it++) { auto& [u, v] = eds[*it]; for (int w : {u, v}) { if (ids[w] != -1) continue; - ids[w] = sz(adj); - vs[sz(adj)] = w; - adj.emplace_back(); + ids[w] = sz(g); + vs[sz(g)] = w; + g.emplace_back(); } u = ids[u], v = ids[v]; - if (*it <= mid) adj[u].push_back(v); + if (*it <= mid) g[u].push_back(v); } - rep(i, 0, sz(adj)) ids[vs[i]] = -1; - scc_id = scc(adj).second; + rep(i, 0, sz(g)) ids[vs[i]] = -1; + scc_id = scc(g).second; auto split = partition(el, er, [&](int i) { return scc_id[eds[i][0]] == scc_id[eds[i][1]]; }); diff --git a/library/graphs/uncommon/block_vertex_tree.hpp b/library/graphs/uncommon/block_vertex_tree.hpp index e69b839f8..74696b0c9 100644 --- a/library/graphs/uncommon/block_vertex_tree.hpp +++ b/library/graphs/uncommon/block_vertex_tree.hpp @@ -1,9 +1,9 @@ #pragma once #include "cuts.hpp" //! @code -//! vector>> adj(n); -//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m); -//! auto bvt = block_vertex_tree(adj, num_bccs, bcc_id); +//! vector>> g(n); +//! auto [num_bccs, bcc_id, is_cut] = cuts(g, m); +//! auto bvt = block_vertex_tree(g, num_bccs, bcc_id); //! //! //to loop over each unique bcc containing a node u: //! for (int bccid : bvt[v]) { @@ -16,13 +16,13 @@ //! [n, n + num_bccs) are BCC nodes //! @time O(n + m) //! @time O(n) -auto block_vertex_tree(const auto& adj, int num_bccs, +auto block_vertex_tree(const auto& g, int num_bccs, const vi& bcc_id) { - int n = sz(adj); + int n = sz(g); vector bvt(n + num_bccs); vector vis(num_bccs); rep(i, 0, n) { - for (auto [_, e_id] : adj[i]) { + for (auto [_, e_id] : g[i]) { int bccid = bcc_id[e_id]; if (!vis[bccid]) { vis[bccid] = 1; diff --git a/library/graphs/uncommon/bridge_tree.hpp b/library/graphs/uncommon/bridge_tree.hpp index 3386ef3ec..276febb4c 100644 --- a/library/graphs/uncommon/bridge_tree.hpp +++ b/library/graphs/uncommon/bridge_tree.hpp @@ -1,16 +1,16 @@ #pragma once #include "bridges.hpp" //! @code -//! vector>> adj(n); -//! auto [num_ccs, br_id, is_br] = bridges(adj, m); -//! auto bt = bridge_tree(adj, num_ccs, br_id, is_br); +//! vector>> g(n); +//! auto [num_ccs, br_id, is_br] = bridges(g, m); +//! auto bt = bridge_tree(g, num_ccs, br_id, is_br); //! @endcode //! @time O(n + m) //! @space O(n) -auto bridge_tree(const auto& adj, int num_ccs, +auto bridge_tree(const auto& g, int num_ccs, const vi& br_id, const vi& is_br) { vector tree(num_ccs); - rep(i, 0, sz(adj)) for (auto [u, e_id] : adj[i]) if ( + rep(i, 0, sz(g)) for (auto [u, e_id] : g[i]) if ( is_br[e_id]) tree[br_id[i]] .push_back(br_id[u]); return tree; diff --git a/library/graphs/uncommon/bridges.hpp b/library/graphs/uncommon/bridges.hpp index cddd9c191..01d5f7868 100644 --- a/library/graphs/uncommon/bridges.hpp +++ b/library/graphs/uncommon/bridges.hpp @@ -1,27 +1,27 @@ #pragma once //! https://cp-algorithms.com/graph/bridge-searching.html //! @code -//! vector>> adj(n); +//! vector>> g(n); //! rep (i, 0, m) { //! int u, v; //! cin >> u >> v; //! u--, v--; -//! adj[u] += {v, i}; -//! adj[v] += {u, i}; +//! g[u] += {v, i}; +//! g[v] += {u, i}; //! } -//! auto [num_ccs, br_id, is_br] = bridges(adj, m); +//! auto [num_ccs, br_id, is_br] = bridges(g, m); //! @endcode //! is_br[edge id] = 1 iff bridge edge //! br_id[v] = id, 0<=id int { int low = tin[u] = ++q; st[s++] = u; - for (auto [v, e] : adj[u]) + for (auto [v, e] : g[u]) if (e != p && br_id[v] < 0) low = min(low, tin[v] ?: dfs(dfs, v, e)); if (tin[u] == low) { diff --git a/library/graphs/uncommon/complement_graph_ccs.hpp b/library/graphs/uncommon/complement_graph_ccs.hpp index 864a8de75..a69e8d3f0 100644 --- a/library/graphs/uncommon/complement_graph_ccs.hpp +++ b/library/graphs/uncommon/complement_graph_ccs.hpp @@ -1,7 +1,7 @@ #pragma once //! @code -//! vector> adj; -//! vi cc_id = get_complement_graph_ccs(adj); +//! vector> g; +//! vi cc_id = get_complement_graph_ccs(g); //! @endcode //! 0<=cc_id[v] is_adj(n); + vector is_g(n); for (int cnt = 0; !empty(unseen); cnt++) { int s = unseen.back(); unseen.pop_back(); @@ -21,10 +21,10 @@ vi get_complement_graph_ccs(const auto& adj) { for (queue q({s}); !empty(q);) { int v = q.front(); q.pop(); - for (int u : adj[v]) is_adj[u] = 1; + for (int u : g[v]) is_g[u] = 1; vi nxt_unseen; for (int u : unseen) { - if (is_adj[u]) { + if (is_g[u]) { nxt_unseen.push_back(u); } else { cc_id[u] = cnt; @@ -32,7 +32,7 @@ vi get_complement_graph_ccs(const auto& adj) { } } swap(unseen, nxt_unseen); - for (int u : adj[v]) is_adj[u] = 0; + for (int u : g[v]) is_g[u] = 0; } } return cc_id; diff --git a/library/graphs/uncommon/cuts.hpp b/library/graphs/uncommon/cuts.hpp index 6a5fd7ba1..8986ae2bb 100644 --- a/library/graphs/uncommon/cuts.hpp +++ b/library/graphs/uncommon/cuts.hpp @@ -1,27 +1,27 @@ #pragma once //! https://cp-algorithms.com/graph/cutpoints.html //! @code -//! vector>> adj(n); +//! vector>> g(n); //! rep (i, 0, m) { //! int u, v; //! cin >> u >> v; //! u--, v--; //! //self edges not allowed -//! adj[u] += {v, i}; -//! adj[v] += {u, i}; +//! g[u] += {v, i}; +//! g[v] += {u, i}; //! } -//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m); +//! auto [num_bccs, bcc_id, is_cut] = cuts(g, m); //! @endcode //! is_cut[v] = 1 iff cut node //! bcc_id[edge id] = id, 0<=id int { int low = tin[u] = ++q; - for (auto [v, e] : adj[u]) { + for (auto [v, e] : g[u]) { assert(u != v); if (e == p) continue; if (tin[v] < tin[u]) st[s++] = e; diff --git a/library/graphs/uncommon/enumerate_triangles.hpp b/library/graphs/uncommon/enumerate_triangles.hpp index 5c50437de..7108a2a51 100644 --- a/library/graphs/uncommon/enumerate_triangles.hpp +++ b/library/graphs/uncommon/enumerate_triangles.hpp @@ -11,16 +11,16 @@ void enumerate_triangles(const vector& edges, int n, auto f) { vi deg(n); for (auto [u, v] : edges) deg[u]++, deg[v]++; - vector adj(n); + vector g(n); for (auto [u, v] : edges) { if (tie(deg[u], u) > tie(deg[v], v)) swap(u, v); - adj[u].push_back(v); + g[u].push_back(v); } vector seen(n); for (auto [u, v] : edges) { - for (int w : adj[u]) seen[w] = 1; - for (int w : adj[v]) + for (int w : g[u]) seen[w] = 1; + for (int w : g[v]) if (seen[w]) f(u, v, w); - for (int w : adj[u]) seen[w] = 0; + for (int w : g[u]) seen[w] = 0; } } diff --git a/library/trees/centroid_decomp.hpp b/library/trees/centroid_decomp.hpp index 43f6f6c50..734a29e77 100644 --- a/library/trees/centroid_decomp.hpp +++ b/library/trees/centroid_decomp.hpp @@ -1,30 +1,30 @@ #pragma once //! @code -//! vector> adj(n); -//! centroid(adj, [&](int cent, int par_cent) {}); +//! vector> g(n); +//! centroid(g, [&](int cent, int par_cent) {}); //! @endcode //! @time O(n log n) //! @space O(n) -void centroid(auto& adj, auto f) { - vi siz(sz(adj)); +void centroid(auto& g, auto f) { + vi siz(sz(g)); auto dfs_sz = [&](auto&& dfs_sz, int u, int p) -> void { siz[u] = 1; - for (int v : adj[u]) + for (int v : g[u]) if (v != p) dfs_sz(dfs_sz, v, u), siz[u] += siz[v]; }; auto dfs = [&](auto&& dfs, int u, int p) -> void { dfs_sz(dfs_sz, u, -1); for (int w = -1, sz_root = siz[u];;) { - auto big_ch = ranges::find_if(adj[u], [&](int v) { + auto big_ch = ranges::find_if(g[u], [&](int v) { return v != w && 2 * siz[v] > sz_root; }); - if (big_ch == end(adj[u])) break; + if (big_ch == end(g[u])) break; w = u, u = *big_ch; } f(u, p); - for (int v : adj[u]) { - iter_swap(ranges::find(adj[v], u), rbegin(adj[v])); - adj[v].pop_back(); + for (int v : g[u]) { + iter_swap(ranges::find(g[v], u), rbegin(g[v])); + g[v].pop_back(); dfs(dfs, v, u); } }; diff --git a/library/trees/edge_cd.hpp b/library/trees/edge_cd.hpp index de868ac87..2bad93720 100644 --- a/library/trees/edge_cd.hpp +++ b/library/trees/edge_cd.hpp @@ -4,21 +4,21 @@ //! https://codeforces.com/blog/entry/142176 //! https://youtu.be/wDwaMo5xa-k //! @code -//! vector> adj(n); -//! edge_cd(adj, [&](int cent, int m) { -//! // subtrees of [0, m) of adj[cent]: 1st edge-set -//! // subtrees of [m, sz(adj[cent])): 2nd edge-set +//! vector> g(n); +//! edge_cd(g, [&](int cent, int m) { +//! // subtrees of [0, m) of g[cent]: 1st edge-set +//! // subtrees of [m, sz(g[cent])): 2nd edge-set //! }); //! @endcode //! handle single-edge-paths separately //! @time O(n logφ n) //! @space O(n) -template void edge_cd(vector& adj, auto f) { - vi siz(sz(adj)); +template void edge_cd(vector& g, auto f) { + vi siz(sz(g)); auto cent = [&](auto&& cent, int u, int p, int m) -> int { siz[u] = 1; - for (int v : adj[u]) + for (int v : g[u]) if (v != p) { int c = cent(cent, v, u, m); if (c != -1) return c; @@ -32,16 +32,16 @@ template void edge_cd(vector& adj, auto f) { if (m < 2) return; u = cent(cent, u, -1, m); int sum = 0; - auto it = partition(all(adj[u]), [&](int v) { + auto it = partition(all(g[u]), [&](int v) { ll x = sum + siz[v]; return x * x < m * (m - x) ? sum += siz[v], 1 : 0; }); - f(u, it - begin(adj[u])); - G oth(it, end(adj[u])); - adj[u].erase(it, end(adj[u])); + f(u, it - begin(g[u])); + G oth(it, end(g[u])); + g[u].erase(it, end(g[u])); dfs(dfs, u, sum); - swap(adj[u], oth); + swap(g[u], oth); dfs(dfs, u, m - sum); }; - dfs(dfs, 0, sz(adj) - 1); + dfs(dfs, 0, sz(g) - 1); }; diff --git a/library/trees/extra_members/virtual_tree.hpp b/library/trees/extra_members/virtual_tree.hpp index 5559fa0ff..2526dc0e0 100644 --- a/library/trees/extra_members/virtual_tree.hpp +++ b/library/trees/extra_members/virtual_tree.hpp @@ -1,7 +1,7 @@ //! https://github.com/kth-competitive-programming/kactl/blob/main/content/graph/CompressTree.h //! @code -//! vector adj(n); -//! LCA lca(adj); +//! vector g(n); +//! LCA lca(g); //! auto [par, orig_node] = //! lca.compress_tree(subset); //! @endcode diff --git a/library/trees/hld.hpp b/library/trees/hld.hpp index 9c9fd5848..b2be04975 100644 --- a/library/trees/hld.hpp +++ b/library/trees/hld.hpp @@ -1,8 +1,8 @@ #pragma once //! https://github.com/kth-competitive-programming/kactl/blob/main/content/graph/HLD.h //! @code -//! vector> adj(n); -//! HLD<0> hld(adj); +//! vector> g(n); +//! HLD<0> hld(g); //! hld.path(u, v, [&](int l, int r) { // [l, r) //! }); //! auto [l, r] = hld.subtree(u); // [l, r) @@ -13,24 +13,23 @@ template struct HLD { int n; vi p, siz, rt, tin; - HLD(auto& adj): - n(sz(adj)), p(n), siz(n, 1), rt(n), tin(n) { + HLD(auto& g): n(sz(g)), p(n), siz(n, 1), rt(n), tin(n) { auto dfs1 = [&](auto&& dfs1, int u) -> void { - for (int& v : adj[u]) { - iter_swap(ranges::find(adj[v], u), rbegin(adj[v])); - adj[v].pop_back(); + for (int& v : g[u]) { + iter_swap(ranges::find(g[v], u), rbegin(g[v])); + g[v].pop_back(); p[v] = u; dfs1(dfs1, v); siz[u] += siz[v]; - if (siz[v] > siz[adj[u][0]]) swap(v, adj[u][0]); + if (siz[v] > siz[g[u][0]]) swap(v, g[u][0]); } }; dfs1(dfs1, 0); int tim = 0; auto dfs2 = [&](auto&& dfs2, int u) -> void { tin[u] = tim++; - for (int v : adj[u]) { - rt[v] = (v == adj[u][0] ? rt[u] : v); + for (int v : g[u]) { + rt[v] = (v == g[u][0] ? rt[u] : v); dfs2(dfs2, v); } }; diff --git a/library/trees/lca_rmq.hpp b/library/trees/lca_rmq.hpp index d031573dd..1b87f7ef7 100644 --- a/library/trees/lca_rmq.hpp +++ b/library/trees/lca_rmq.hpp @@ -3,8 +3,8 @@ #include "../data_structures_[l,r)/rmq.hpp" //! https://github.com/kth-competitive-programming/kactl/blob/main/content/graph/LCA.h //! @code -//! vector> adj(n); -//! LCA lca(adj); +//! vector> g(n); +//! LCA lca(g); //! @endcode //! @time O(nlogn + q) //! @space O(nlogn) @@ -13,12 +13,12 @@ struct LCA { int n; vi tin, siz, d, p; RMQ> rmq = {{}, NULL}; - LCA(const auto& adj): - n(sz(adj)), tin(n), siz(n, 1), d(n), p(n) { + LCA(const auto& g): + n(sz(g)), tin(n), siz(n, 1), d(n), p(n) { vi order; auto dfs = [&](auto&& dfs, int u) -> void { tin[u] = sz(order), order.push_back(u); - for (int v : adj[u]) + for (int v : g[u]) if (v != p[u]) d[v] = d[p[v] = u] + 1, dfs(dfs, v), siz[u] += siz[v]; diff --git a/library/trees/linear_lca.hpp b/library/trees/linear_lca.hpp index aeb6ba0aa..6fd4cb7f6 100644 --- a/library/trees/linear_lca.hpp +++ b/library/trees/linear_lca.hpp @@ -1,8 +1,8 @@ #pragma once //! https://codeforces.com/blog/entry/125371 //! @code -//! vector> adj(n); -//! linear_lca llca(adj); +//! vector> g(n); +//! linear_lca llca(g); //! @endcode //! @time O(n + q) //! @space O(n) @@ -10,13 +10,13 @@ int lsb(int x) { return x & -x; } struct linear_lca { int n; vi d, in, asc, head; - linear_lca(const auto& adj): - n(sz(adj)), d(n), in(n), asc(n), head(n + 1) { + linear_lca(const auto& g): + n(sz(g)), d(n), in(n), asc(n), head(n + 1) { vector order; auto dfs = [&](auto&& dfs, int u, int p) -> void { order.emplace_back(u, p); in[u] = sz(order); - for (int v : adj[u]) + for (int v : g[u]) if (v != p) { d[v] = 1 + d[u]; dfs(dfs, v, u); diff --git a/library/trees/shallowest_decomp_tree.hpp b/library/trees/shallowest_decomp_tree.hpp index a36320712..f25c7503d 100644 --- a/library/trees/shallowest_decomp_tree.hpp +++ b/library/trees/shallowest_decomp_tree.hpp @@ -1,17 +1,17 @@ #pragma once //! https://codeforces.com/blog/entry/125018 //! @code -//! vector> adj(n); -//! shallowest(adj, [&](int cent) { +//! vector> g(n); +//! shallowest(g, [&](int cent) { //! }); //! @endcode //! @time O(n log n) //! @space O(n) -void shallowest(auto& adj, auto f) { - vector order(bit_width(size(adj))); +void shallowest(auto& g, auto f) { + vector order(bit_width(size(g))); auto dfs = [&](auto&& dfs, int u, int p) -> int { int once = 0, twice = 0; - for (int v : adj[u]) + for (int v : g[u]) if (v != p) { int dp = dfs(dfs, v, u); twice |= once & dp, once |= dp; @@ -24,8 +24,8 @@ void shallowest(auto& adj, auto f) { for (const vi& vec : order | views::reverse) for (int u : vec) { f(u); - for (int v : adj[u]) - iter_swap(ranges::find(adj[v], u), rbegin(adj[v])), - adj[v].pop_back(); + for (int v : g[u]) + iter_swap(ranges::find(g[v], u), rbegin(g[v])), + g[v].pop_back(); } } diff --git a/library/trees/tree_lift.hpp b/library/trees/tree_lift.hpp index e2739142f..22dfb4bea 100644 --- a/library/trees/tree_lift.hpp +++ b/library/trees/tree_lift.hpp @@ -1,8 +1,8 @@ #pragma once //! https://github.com/ucf-programming-team/hackpack-cpp/blob/master/content/graphs/TreeLifting.h //! @code -//! vector> adj(n); -//! tree_lift tree_l(adj); +//! vector> g(n); +//! tree_lift tree_l(g); //! tree_l.kth_par(v, k); // k edges up from v //! tree_l.kth_par(v, 1); // v's parent //! @endcode @@ -10,11 +10,11 @@ //! @space O(n) struct tree_lift { vi d, p, j; - tree_lift(const auto& adj): d(sz(adj)), p(d), j(d) { + tree_lift(const auto& g): d(sz(g)), p(d), j(d) { auto dfs = [&](auto&& dfs, int u) -> void { int up = d[u] + d[j[j[u]]] == 2 * d[j[u]] ? j[j[u]] : u; - for (int v : adj[u]) + for (int v : g[u]) if (v != p[u]) d[v] = d[p[v] = u] + 1, j[v] = up, dfs(dfs, v); }; diff --git a/library/trees/uncommon/ladder_decomposition.hpp b/library/trees/uncommon/ladder_decomposition.hpp index 48992cbe7..3e8844ff0 100644 --- a/library/trees/uncommon/ladder_decomposition.hpp +++ b/library/trees/uncommon/ladder_decomposition.hpp @@ -3,7 +3,7 @@ //! https://codeforces.com/blog/entry/71567#comment-559299 //! https://youtu.be/0rCFkuQS968 //! @code -//! ladder ld(adj); +//! ladder ld(g); //! // KACTL functions //! int kth_par = jmp(ld.jmp, u, k); //! int curr_lca = lca(ld.jmp, ld.d, u, v); @@ -12,14 +12,14 @@ struct ladder { int n; vi d, p, leaf, idx, lad; vector jmp; - //! @param adj forest (rooted or unrooted) + //! @param g forest (rooted or unrooted) //! @time O(n log n) //! @space O(n log n) for jmp. Everything else is O(n) - ladder(const auto& adj): - n(sz(adj)), d(n), p(n), leaf(n), idx(n), lad(2 * n) { + ladder(const auto& g): + n(sz(g)), d(n), p(n), leaf(n), idx(n), lad(2 * n) { auto dfs = [&](auto&& dfs, int u) -> void { leaf[u] = u; - for (int v : adj[u]) + for (int v : g[u]) if (v != p[u]) { d[v] = d[p[v] = u] + 1; dfs(dfs, v); diff --git a/library/trees/uncommon/linear_kth_par.hpp b/library/trees/uncommon/linear_kth_par.hpp index 606d6ecf1..8801a3c01 100644 --- a/library/trees/uncommon/linear_kth_par.hpp +++ b/library/trees/uncommon/linear_kth_par.hpp @@ -1,8 +1,8 @@ #pragma once //! https://codeforces.com/blog/entry/126580 //! @code -//! vector> adj(n); -//! linear_kth_par kp(adj); +//! vector> g(n); +//! linear_kth_par kp(g); //! kp.kth_par(v, k); // k edges up from v //! kp.kth_par(v, 1); // v's parent //! @endcode @@ -12,8 +12,8 @@ template struct linear_kth_par { int n; vi d, leaf, pos, jmp; vector lad; - linear_kth_par(const auto& adj): - n(sz(adj)), d(n), leaf(n), pos(n), jmp(2 * n), lad(n) { + linear_kth_par(const auto& g): + n(sz(g)), d(n), leaf(n), pos(n), jmp(2 * n), lad(n) { static_assert(KAPPA >= 1); int t = 1; vi st(n); @@ -25,7 +25,7 @@ template struct linear_kth_par { int& l = leaf[u] = st[d[u]] = u; pos[u] = t; calc(d[u]); - for (int v : adj[u]) + for (int v : g[u]) if (v != p) { d[v] = 1 + d[u]; dfs(dfs, v, u); diff --git a/library/trees/uncommon/subtree_isomorphism.hpp b/library/trees/uncommon/subtree_isomorphism.hpp index af0be0d4e..708941d89 100644 --- a/library/trees/uncommon/subtree_isomorphism.hpp +++ b/library/trees/uncommon/subtree_isomorphism.hpp @@ -1,20 +1,20 @@ #pragma once //! @code -//! vector> adj(n); +//! vector> g(n); //! auto [num_distinct_subtrees, iso_id] = -//! subtree_iso(adj); +//! subtree_iso(g); //! @endcode //! - 0 <= iso_id[v] < num_distinct_subtrees //! - iso_id[u] == iso_id[v] iff subtree u is //! isomorphic to subtree v //! @time O(n log n) //! @space O(n) -auto subtree_iso(const auto& adj) { - vi iso_id(sz(adj), -1); +auto subtree_iso(const auto& g) { + vi iso_id(sz(g), -1); map hashes; auto dfs = [&](auto&& dfs, int u, int p) -> int { vi ch_ids; - for (int v : adj[u]) + for (int v : g[u]) if (v != p) ch_ids.push_back(dfs(dfs, v, u)); ranges::sort(ch_ids); return iso_id[u] = diff --git a/tests/library_checker_aizu_tests/dsu/kruskal_tree_aizu.test.cpp b/tests/library_checker_aizu_tests/dsu/kruskal_tree_aizu.test.cpp index 28e3edf36..31e3999db 100644 --- a/tests/library_checker_aizu_tests/dsu/kruskal_tree_aizu.test.cpp +++ b/tests/library_checker_aizu_tests/dsu/kruskal_tree_aizu.test.cpp @@ -31,7 +31,7 @@ int main() { vector depth(2 * n); vector actual_par(2 * n, -1); auto dfs = [&](auto&& self, int v) -> void { - for (int u : kt.adj[v]) { + for (int u : kt.g[v]) { depth[u] = 1 + depth[v]; actual_par[u] = v; self(self, u);