---
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, [], ""),
    ],
  }
};

<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} />