This repository has been archived on 2022-06-22. You can view files and clone it, but cannot push or open issues or pull requests.
usaco-guide/content/6_Plat/BCC_2CC.mdx

128 lines
3.6 KiB
Text

---
id: BCC-2CC
title: "BCCs and 2CCs"
author: Benjamin Qi
prerequisites:
- Silver - DFS
- Platinum - Binary Jumping
description: "Precomputing parents of nodes in powers of two to find the xth parent of a node efficently."
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", "Very Hard", false, [], ""),
new Problem("DMOJ", "Investment", "tle17c1p6", "Hard", false, [], ""),
new Problem("ojuz", "CEOI - Pipes", "CEOI15_pipes", "Hard", false, [], ""),
],
}
};
<resources>
<resource source="CF" title="DFS Tree + Bridges" url="blog/entry/68138"> </resource>
</resources>
## 2-Edge-Connected Components
<problems-list problems={metadata.problems.sam2} />
(implementation)
### With DSU
<problems-list problems={metadata.problems.disrupt} />
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?)
<spoiler title="Code">
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<vi> 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
}
};
```
</spoiler>
### Problems
<problems-list problems={metadata.problems.probs2} />
- SRM 787 1000
## [Biconnected Components](https://en.wikipedia.org/wiki/Biconnected_component)
<problems-list problems={metadata.problems.bccSam} />
note that BCCs contain EDGES not VERTICES
Related topics include
- Articulation Points
- Bridges
- Block-Cut Tree
### Tutorial
<resources>
<resource source="GFG" title="Articulation Points (aka Cut Vertices)" url="articulation-points-or-cut-vertices-in-a-graph">maybe not completely correct</resource>
</resources>
(implementation)
### Problems
<problems-list problems={metadata.problems.gen} />