--- id: BCC-2CC title: "BCCs and 2CCs" author: Benjamin Qi prerequisites: - Silver - DFS - Platinum - Binary Jumping description: "?" frequency: 1 --- import { Problem } from "../models"; export const metadata = { problems: { sam2: [ new Problem("YS", "Two-Edge-Connected Components", "two_edge_connected_components", "Easy", false, [], ""), ], disrupt: [ new Problem("Plat", "Disruption", "842", "Normal", false, ["Merging"]), ], probs2: [ new Problem("CSA", "One-Way Streets", "one-way-streets", "Easy", false, [], ""), ], bccSam: [ new Problem("CSES", "Forbidden Cities", "1705", "Normal", false, [], ""), ], gen: [ new Problem("POI", "Blockade", "https://szkopul.edu.pl/problemset/problem/eDt8w290owtatmCjad0O0ywk/site/?key=statement", "Normal", false, [], ""), new Problem("ojuz", "APIO - Duathlon", "APIO18_duathlon", "Normal", false, [], ""), new Problem("Plat", "Push a Box", "769", "Hard", false, [], ""), new Problem("DMOJ", "Investment", "tle17c1p6", "Hard", false, [], ""), new Problem("ojuz", "CEOI - Pipes", "CEOI15_pipes", "Hard", false, [], ""), ], } }; ## 2-Edge-Connected Components (implementation) ### With DSU The analysis for the above problem mentions an $O(m\alpha(n))$ solution. Although this is not a two-connected component problem, we can in fact use DSU to generate two-connected components. (explanation?) The DSU operations take $O(\log n)$ rather than $O(\alpha(n))$ because the DSU does not use union by size, but it's easy to change this. ```cpp struct TwoEdgeCC { struct { vi e; void init(int n) { e = vi(n,-1); } int get(int x) { return e[x] < 0 ? x : e[x] = get(e[x]); } bool unite(int x, int y) { // set par[y] = x x = get(x), y = get(y); if (x == y) return 0; e[x] += e[y]; e[y] = x; return 1; } } DSU; int N; vector adj; vi depth, par; vpi extra; void init(int _N) { N = _N; DSU.init(N); adj.rsz(N), depth.rsz(N), par = vi(N,-1); } void dfs(int x) { trav(t,adj[x]) if (t != par[x]) par[t] = x, depth[t] = depth[x]+1, dfs(t); } void ae(int a, int b) { if (DSU.unite(a,b)) adj[a].pb(b), adj[b].pb(a); // edge of forest else extra.pb({a,b}); // extra edge } void ad(int a, int b) { while (1) { a = DSU.get(a), b = DSU.get(b); if (a == b) return; if (depth[a] < depth[b]) swap(a,b); assert(par[a] != -1 && DSU.unite(par[a],a)); } } void gen() { F0R(i,N) if (par[i] == -1) dfs(i); // independently for each connected component DSU.init(N); trav(t,extra) ad(t.f,t.s); // add non-spanning edges } }; ``` ### Problems - SRM 787 1000 ## [Biconnected Components](https://en.wikipedia.org/wiki/Biconnected_component) note that BCCs contain EDGES not VERTICES Related topics include - Articulation Points - Bridges - Block-Cut Tree ### Tutorial maybe not completely correct (implementation) ### Problems