Strongly Connected Components & Bridges

SCC, bridge ও articulation point

Read: ~45 min Advanced 6 practice problems Live code runner

1. Definitions

  • SCC (directed): a maximal vertex set where every pair u, v has paths u → v and v → u.
  • Bridge (undirected): an edge whose removal increases the number of connected components.
  • Articulation point (undirected): a vertex whose removal disconnects the graph.
SCC → directed graph-এ পরস্পরে যাওয়া যায় এমন vertex-এর সর্বোচ্চ সেট। Bridge → যে edge সরালে graph ভেঙে যায়। Articulation → যে vertex সরালে graph ভেঙে যায়।

2. Tarjan's Magic — disc[] and low[]

One DFS, two arrays:

  • disc[u] = the time when DFS first visits u.
  • low[u] = the smallest disc reachable from u via tree edges + at most one back edge.

From these:

  • Edge (u, v) is a bridge if low[v] > disc[u].
  • Vertex u is an articulation point if it is the root with ≥ 2 DFS children, OR it is non-root and some child v has low[v] ≥ disc[u].
  • For Tarjan SCC, when low[u] == disc[u], u is the root of an SCC — pop from a stack until u is popped.

3. Tarjan's SCC Implementation

tarjan_scc.cpp
#include <bits/stdc++.h>
using namespace std;

int n, timer = 0;
vector<vector<int>> adj;
vector<int> disc, low, comp;
vector<bool> onStk;
stack<int> stk;
int sccId = 0;

void dfs(int u) {
    disc[u] = low[u] = timer++;
    stk.push(u); onStk[u] = true;
    for (int v : adj[u]) {
        if (disc[v] == -1) {
            dfs(v);
            low[u] = min(low[u], low[v]);
        } else if (onStk[v]) {
            low[u] = min(low[u], disc[v]);
        }
    }
    if (low[u] == disc[u]) {
        while (true) {
            int v = stk.top(); stk.pop(); onStk[v] = false;
            comp[v] = sccId;
            if (v == u) break;
        }
        sccId++;
    }
}

int main() {
    n = 7;
    adj.assign(n, {});
    vector<pair<int,int>> e = {{0,1},{1,2},{2,0},{2,3},{3,4},{4,5},{5,3},{5,6}};
    for (auto [u, v] : e) adj[u].push_back(v);

    disc.assign(n, -1); low.assign(n, 0);
    onStk.assign(n, false); comp.assign(n, -1);
    for (int i = 0; i < n; i++) if (disc[i] == -1) dfs(i);

    cout << "SCC count = " << sccId << "\n";
    for (int i = 0; i < n; i++)
        cout << "vertex " << i << " → SCC " << comp[i] << "\n";
}

4. Bridges in Undirected Graphs

One DFS, similar low-link logic. For tree edge (u, v): if low[v] > disc[u], then no back edge from v's subtree reaches u or earlier — removing (u, v) disconnects v's subtree. Bridge!

bridges.cpp
#include <bits/stdc++.h>
using namespace std;

int n, T = 0;
vector<vector<int>> adj;
vector<int> disc, low;
vector<pair<int,int>> bridges;

void dfs(int u, int p) {
    disc[u] = low[u] = T++;
    for (int v : adj[u]) {
        if (v == p) continue;
        if (disc[v] == -1) {
            dfs(v, u);
            low[u] = min(low[u], low[v]);
            if (low[v] > disc[u]) bridges.push_back({u, v});
        } else {
            low[u] = min(low[u], disc[v]);
        }
    }
}

int main() {
    n = 5;
    adj.assign(n, {});
    vector<pair<int,int>> e = {{0,1},{1,2},{2,0},{1,3},{3,4}};
    for (auto [u, v] : e) { adj[u].push_back(v); adj[v].push_back(u); }
    disc.assign(n, -1); low.assign(n, 0);
    dfs(0, -1);
    for (auto [u, v] : bridges)
        cout << "bridge: " << u << "-" << v << "\n";
}

5. Real-World Use

  • Deadlock detection: SCC of size > 1 in a wait-for graph signals a deadlock.
  • Web crawler: SCCs of the link graph reveal "communities" of mutually reachable pages.
  • Network resilience: bridges and articulation points identify single-points-of-failure in physical networks.
  • 2-SAT: reduces to SCC on the implication graph.
Tarjan-এর low-link বুঝলে এক DFS-এই SCC, bridge, articulation — তিনটিই বের হয়। ICPC-এর "graph theory" round-এ এটি অত্যন্ত শক্তিশালী।

6. Practice Problems

  1. Count SCCs in the directed graph 0→1, 1→2, 2→0, 2→3, 3→4, 4→5, 5→3.
    দেওয়া graph-এর SCC সংখ্যা।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: {0, 1, 2} forms one SCC; {3, 4, 5} forms another. Total 2 SCCs.

  2. Critical connections in a network — find all bridges.
    Critical connections — সব bridge খুঁজুন।
    ✨ Show Answer (উত্তর দেখুন)

    Approach: the bridges code above. Output (u, v) pairs where low[v] > disc[u].

  3. Find all articulation points of an undirected graph.
    সব articulation point।
    ✨ Show Answer (উত্তর দেখুন)

    Approach: same DFS. u is an articulation if (a) u is the root and has ≥ 2 DFS children, OR (b) u is not the root and some child v has low[v] ≥ disc[u].

  4. Determine if a directed graph is strongly connected.
    Directed graph strongly connected কিনা।
    ✨ Show Answer (উত্তর দেখুন)

    Approach: run Tarjan; SCC count == 1 means strongly connected. Or — Kosaraju: BFS/DFS forward from any vertex must reach all; same on the reverse graph. Both O(V + E).

  5. Minimum edges to add to make a digraph strongly connected.
    Strongly connected করতে minimum edge।
    ✨ Show Answer (উত্তর দেখুন)

    Answer: condense the graph into its SCC DAG. Count vertices with indegree 0 (call it a) and outdegree 0 (call it b). The answer is max(a, b), with the corner case of a single SCC (= 0 edges needed).

  6. Why does Tarjan's algorithm need onStk? Why not use disc[v] != -1?
    Tarjan-এ onStk কেন দরকার?
    ✨ Show Answer (উত্তর দেখুন)

    Answer: not all visited neighbours are part of the current SCC. onStk identifies vertices in the current DFS path's open SCC. Without it, we would update low[u] using disc of vertices in finished SCCs, breaking the algorithm.

Summary — Module 30

Tarjan's disc/low framework solves SCC (directed), bridges (undirected), and articulation points — all in O(V + E). 2-SAT, deadlock detection, and network reliability all reduce to these. With this, Phase 6 ends.

disc + low — দুটি array, এক DFS, তিনটি সমস্যার সমাধান। Phase 6 শেষ — পরবর্তী module-এ network flow।

Next Module → Network Flow: Max-Flow, Min-Cut।