Algorithms

Advanced Graph Algorithms

πŸ“‹ At a Glance

AspectDetails
Time to Read35 minutes
PrerequisitesPart 11 (Graph Traversal), Part 12 (Shortest Path)
Key ConceptsStrongly Connected Components, Articulation Points, Max Flow, Bipartite Matching
Difficulty⭐⭐⭐⭐ (Advanced)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           ADVANCED GRAPH ALGORITHMS LANDSCAPE                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  CONNECTIVITY                    FLOW NETWORKS                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”‚
β”‚  β”‚ Strongly        β”‚            β”‚ Maximum Flow    β”‚             β”‚
β”‚  β”‚ Connected       β”‚            β”‚ ─────────────── β”‚             β”‚
β”‚  β”‚ Components      β”‚            β”‚ Ford-Fulkerson  β”‚             β”‚
β”‚  β”‚ ─────────────── β”‚            β”‚ Edmonds-Karp    β”‚             β”‚
β”‚  β”‚ Tarjan's O(V+E) β”‚            β”‚ Push-Relabel    β”‚             β”‚
β”‚  β”‚ Kosaraju's      β”‚            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β”‚                       β”‚
β”‚          β”‚                              β”‚                       β”‚
β”‚          β–Ό                              β–Ό                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”‚
β”‚  β”‚ Critical Points β”‚            β”‚ Min Cut         β”‚             β”‚
β”‚  β”‚ ─────────────── β”‚            β”‚ ─────────────── β”‚             β”‚
β”‚  β”‚ Articulation    β”‚            β”‚ Max-Flow =      β”‚             β”‚
β”‚  β”‚ Points          β”‚            β”‚ Min-Cut         β”‚             β”‚
β”‚  β”‚ Bridges         β”‚            β”‚ (Duality)       β”‚             β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
β”‚                                         β”‚                       β”‚
β”‚                                         β–Ό                       β”‚
β”‚                                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”‚
β”‚                                 β”‚ Bipartite       β”‚             β”‚
β”‚                                 β”‚ Matching        β”‚             β”‚
β”‚                                 β”‚ ─────────────── β”‚             β”‚
β”‚                                 β”‚ Hungarian Alg   β”‚             β”‚
β”‚                                 β”‚ Hopcroft-Karp   β”‚             β”‚
β”‚                                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎯 What You'll Learn

After completing this article, you will be able to:

  1. Find SCCs: Implement Tarjan's and Kosaraju's algorithms
  2. Identify critical points: Find articulation points and bridges
  3. Solve flow problems: Apply Ford-Fulkerson and Edmonds-Karp
  4. Match bipartite graphs: Use Hungarian algorithm for optimal assignment
  5. Apply min-cut: Understand max-flow min-cut duality

πŸ”₯ Production Story: The Microservice Dependency Nightmare

A fintech company's platform grew to 200+ microservices. One Monday morning, a seemingly minor deployment caused a cascade failure affecting 40% of the system.

The Incident

08:15 - Payment service deployed new version
08:17 - Order service health checks failing
08:19 - Inventory service unresponsive
08:22 - Customer dashboard showing errors
08:25 - Trading halted, revenue loss: $50K/minute

The team had no visibility into service dependencies. They couldn't answer:

  • Which services form tightly coupled groups?
  • Which services, if they fail, would partition the system?
  • What's the maximum throughput between any two services?

The Investigation

The architect analyzed the call graph:

JAVA(14 lines)
Code
Loading syntax highlighter...

The Solution

They applied advanced graph algorithms:

JAVA(40 lines)
Code
Loading syntax highlighter...

The Impact

MetricBeforeAfter
Mean Time to Recovery45 minutes8 minutes
Cascade failures/month121
Critical services identified023
Deployment confidenceLowHigh
The insight: Understanding graph structure transforms reactive firefighting into proactive architecture.

🧠 Mental Model: The City Infrastructure

Think of advanced graph algorithms as city planning tools:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    CITY INFRASTRUCTURE                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  STRONGLY CONNECTED              ARTICULATION POINTS            β”‚
β”‚  COMPONENTS                      (Single Points of Failure)     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”‚
β”‚  β”‚  Downtown       β”‚            β”‚                 β”‚             β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”  β”Œβ”€β”€β”€β”   β”‚            β”‚    A ─── B      β”‚             β”‚
β”‚  β”‚  β”‚ A │──│ B β”‚   β”‚            β”‚    β”‚            β”‚             β”‚
β”‚  β”‚  β””β”€β”¬β”€β”˜  β””β”€β”¬β”€β”˜   β”‚            β”‚    β–Ό            β”‚             β”‚
β”‚  β”‚    β”‚  β•²β•±   β”‚    β”‚            β”‚   [C] ◄───────  β”‚  C is       β”‚
β”‚  β”‚    β”‚  β•±β•²   β”‚    β”‚            β”‚    β”‚             critical     β”‚
β”‚  β”‚  β”Œβ”€β”΄β”€β”  β”Œβ”€β”΄β”€β”   β”‚            β”‚    β–Ό            β”‚             β”‚
β”‚  β”‚  β”‚ C │──│ D β”‚   β”‚            β”‚    D ─── E      β”‚             β”‚
β”‚  β”‚  β””β”€β”€β”€β”˜  β””β”€β”€β”€β”˜   β”‚            β”‚                 β”‚             β”‚
β”‚  β”‚ All reachable   β”‚            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
β”‚  β”‚ from each other β”‚                                            β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                            β”‚
β”‚                                                                 β”‚
β”‚  MAX FLOW                        BIPARTITE MATCHING             β”‚
β”‚  (Traffic Capacity)              (Job Assignment)               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”‚
β”‚  β”‚     8    5      β”‚            β”‚ Workers  Jobs   β”‚             β”‚
β”‚  β”‚  A ───→ B ───→  β”‚            β”‚    A ──── 1     β”‚             β”‚
β”‚  β”‚  β”‚      β”‚    T  β”‚            β”‚    B ──┬─ 2     β”‚             β”‚
β”‚  β”‚  β”‚3     β”‚2      β”‚            β”‚    C β”€β”€β”˜β”€ 3     β”‚             β”‚
β”‚  β”‚  β–Ό      β–Ό       β”‚            β”‚                 β”‚             β”‚
β”‚  β”‚  S ───→ C ───→  β”‚            β”‚ Maximum         β”‚             β”‚
β”‚  β”‚     6    4      β”‚            β”‚ matching = 3    β”‚             β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Key analogies:
  • SCC = Neighborhoods where you can walk from any point to any other
  • Articulation Point = The only bridge connecting two parts of city
  • Max Flow = Maximum traffic the road network can handle
  • Bipartite Matching = Assigning taxi drivers to passengers optimally

πŸ”¬ Deep Dive: Strongly Connected Components

Understanding SCCs

A Strongly Connected Component is a maximal set of vertices where every vertex is reachable from every other vertex.
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    SCC VISUALIZATION                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  Original Graph:                 SCCs Identified:               β”‚
β”‚                                                                 β”‚
β”‚    1 ──→ 2                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚
β”‚    ↑     ↓                        β”‚ SCC 1   β”‚                   β”‚
β”‚    └──── 3 ──→ 4                  β”‚ {1,2,3} │──→ {4} ──→ {5,6}  β”‚
β”‚              ↓                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    SCC2    SCC3   β”‚
β”‚         5 ←── 6                                                 β”‚
β”‚         └────→                                                  β”‚
β”‚                                                                 β”‚
β”‚  Within SCC: bidirectional reachability                         β”‚
β”‚  Between SCCs: DAG (no cycles possible)                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Kosaraju's Algorithm

Kosaraju's uses two DFS passes - one on original graph, one on reversed:

JAVA(67 lines)
Code
Loading syntax highlighter...
Why it works:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                 KOSARAJU'S INTUITION                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  Pass 1: Record finish times                                    β”‚
β”‚  ─────────────────────────────                                  β”‚
β”‚  Vertices that finish later can reach more vertices             β”‚
β”‚  (they're "upstream" in the SCC DAG)                            β”‚
β”‚                                                                 β”‚
β”‚     SCC_A ──→ SCC_B ──→ SCC_C                                   β”‚
β”‚       β–²                                                         β”‚
β”‚       β”‚                                                         β”‚
β”‚  Finishes last (can reach B and C)                              β”‚
β”‚                                                                 β”‚
β”‚  Pass 2: DFS on reversed graph                                  β”‚
β”‚  ─────────────────────────────                                  β”‚
β”‚  Starting from highest finish time:                             β”‚
β”‚  - Can only reach vertices in SAME SCC                          β”‚
β”‚  - Reverse edges prevent crossing to other SCCs                 β”‚
β”‚                                                                 β”‚
β”‚     SCC_A ←── SCC_B ←── SCC_C   (reversed)                      β”‚
β”‚       β”‚                                                         β”‚
β”‚       └── Start here, stays in SCC_A                            β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Tarjan's Algorithm

Tarjan's is more elegant - single DFS pass using low-link values:

JAVA(75 lines)
Code
Loading syntax highlighter...
Low-link visualization:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    TARJAN'S LOW-LINK                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  Discovery order:  1 β†’ 2 β†’ 3 β†’ 4                                β”‚
β”‚                                                                 β”‚
β”‚    1 ────→ 2                  ids:      1  2  3  4              β”‚
β”‚    ↑       ↓                  lowLinks: 1  1  1  4              β”‚
β”‚    └────── 3 ────→ 4                                            β”‚
β”‚                                                                 β”‚
β”‚  Back edge 3β†’1 updates lowLinks:                                β”‚
β”‚  - lowLink[3] = min(3, id[1]) = 1                               β”‚
β”‚  - lowLink[2] = min(2, lowLink[3]) = 1                          β”‚
β”‚  - lowLink[1] = min(1, lowLink[2]) = 1                          β”‚
β”‚                                                                 β”‚
β”‚  SCC roots: vertices where id[v] == lowLink[v]                  β”‚
β”‚  - Vertex 1: id=1, lowLink=1 β†’ ROOT of SCC {1,2,3}              β”‚
β”‚  - Vertex 4: id=4, lowLink=4 β†’ ROOT of SCC {4}                  β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Comparison

AspectKosaraju'sTarjan's
DFS passes21
Extra spaceO(V) for reverse graphO(V) for stack
SimplicityEasier to understandMore elegant
ConstantsSlightly higherLower
Output orderReverse topologicalReverse topological

πŸ”¬ Deep Dive: Articulation Points and Bridges

Articulation Points

An articulation point (cut vertex) is a vertex whose removal disconnects the graph.
JAVA(81 lines)
Code
Loading syntax highlighter...
Why the conditions work:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              ARTICULATION POINT CONDITIONS                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  Condition 1: Root with 2+ children                             β”‚
β”‚  ──────────────────────────────────                             β”‚
β”‚       β”Œβ”€β”€β”€β”                                                     β”‚
β”‚       β”‚ R β”‚ ← Root                                              β”‚
β”‚      β•±     β•²                                                    β”‚
β”‚  β”Œβ”€β”€β”€β”     β”Œβ”€β”€β”€β”                                                β”‚
β”‚  β”‚ A β”‚     β”‚ B β”‚  Two subtrees                                  β”‚
β”‚  β””β”€β”€β”€β”˜     β””β”€β”€β”€β”˜                                                β”‚
β”‚                                                                 β”‚
β”‚  If R is removed, A and B are disconnected                      β”‚
β”‚  (children in DFS tree have no other connection)                β”‚
β”‚                                                                 β”‚
β”‚  Condition 2: low[v] >= discovery[u]                            β”‚
β”‚  ───────────────────────────────────                            β”‚
β”‚       1                                                         β”‚
β”‚      β•±β”‚                                                         β”‚
β”‚     2 β”‚    discovery[1]=0, low[1]=0                             β”‚
β”‚    β•±β”‚ β”‚    discovery[2]=1, low[2]=0 (back edge to 1)            β”‚
β”‚   3 β”‚ β”‚    discovery[3]=2, low[3]=2 (no back edge!)             β”‚
β”‚     β”‚ β”‚                                                         β”‚
β”‚     β””β”€β”˜    low[3] >= discovery[2] β†’ 2 is articulation           β”‚
β”‚            (3 can't reach above 2 without going through 2)      β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Bridges

A bridge is an edge whose removal disconnects the graph:
JAVA(63 lines)
Code
Loading syntax highlighter...
Bridge vs Articulation Point:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           BRIDGE vs ARTICULATION POINT                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  Articulation: low[v] >= discovery[u]                           β”‚
β”‚  Bridge:       low[v] >  discovery[u]                           β”‚
β”‚                                                                 β”‚
β”‚  Example where u is articulation but (u,v) is NOT bridge:       β”‚
β”‚                                                                 β”‚
β”‚      1 ─── 2                                                    β”‚
β”‚      β”‚    β•±β”‚                                                    β”‚
β”‚      β”‚   β•± β”‚   Multiple edges between 2 and 3                   β”‚
β”‚      β”‚  β•±  β”‚   low[3] = discovery[2] (can reach 2 via other)    β”‚
β”‚      3 β•±β”€β”€β”€β”˜                                                    β”‚
β”‚                                                                 β”‚
β”‚  Vertex 2: articulation (low[3] >= discovery[2])                β”‚
β”‚  Edge 2-3: NOT bridge (low[3] = discovery[2], not >)            β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”¬ Deep Dive: Maximum Flow

The Flow Network

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    FLOW NETWORK CONCEPTS                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  Source (S): produces flow                                      β”‚
β”‚  Sink (T): consumes flow                                        β”‚
β”‚  Capacity: maximum flow an edge can carry                       β”‚
β”‚  Flow: actual flow through an edge                              β”‚
β”‚                                                                 β”‚
β”‚         capacity                                                β”‚
β”‚           10                                                    β”‚
β”‚     S ─────────→ A ─────────→ T                                 β”‚
β”‚           flow=7        8                                       β”‚
β”‚                                                                 β”‚
β”‚  Constraints:                                                   β”‚
β”‚  1. Capacity: flow(e) ≀ capacity(e) for all edges               β”‚
β”‚  2. Conservation: flow_in(v) = flow_out(v) for v β‰  S,T          β”‚
β”‚  3. Non-negative: flow(e) β‰₯ 0                                   β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Ford-Fulkerson Method

The idea: repeatedly find augmenting paths and push flow:

JAVA(70 lines)
Code
Loading syntax highlighter...
Why residual graph works:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                 RESIDUAL GRAPH INTUITION                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  Original:        After flow=3:      Residual:                  β”‚
β”‚                                                                 β”‚
β”‚     cap=5            flow=3             res=2 (can push 2 more) β”‚
β”‚  S ─────→ T       S ═════→ T         S ─────→ T                 β”‚
β”‚                                       ←─────                    β”‚
β”‚                                        res=3 (can "undo" 3)     β”‚
β”‚                                                                 β”‚
β”‚  Backward edge allows:                                          β”‚
β”‚  - Correcting suboptimal path choices                           β”‚
β”‚  - "Rerouting" flow through better paths                        β”‚
β”‚                                                                 β”‚
β”‚  Example where backward edges are essential:                    β”‚
β”‚                                                                 β”‚
β”‚       β”Œβ”€β”€β”€ B ───┐                                               β”‚
β”‚       β”‚   1β”‚1   β”‚                                               β”‚
β”‚    1  β”‚    β”‚    β”‚  1                                            β”‚
β”‚  S ───┴─── A ───┴─── T                                          β”‚
β”‚            1                                                    β”‚
β”‚                                                                 β”‚
│  Path 1: S→B→A→T (flow=1)                                       │
β”‚  Without backward: stuck at max_flow=1                          β”‚
│  With backward: S→A→B→T uses backward A→B, total flow=2         │
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Edmonds-Karp Optimization

Using BFS guarantees O(VEΒ²) complexity:

JAVA(87 lines)
Code
Loading syntax highlighter...

Complexity Analysis

AlgorithmTimeNotes
Ford-Fulkerson (DFS)O(E Γ— max_flow)Can be slow with large capacities
Edmonds-Karp (BFS)O(VEΒ²)Polynomial, practical
Dinic'sO(VΒ²E)Better for dense graphs
Push-RelabelO(VΒ²E) or O(VΒ³)Best for very dense graphs

πŸ”¬ Deep Dive: Min-Cut Max-Flow Theorem

The Duality

Theorem: Maximum flow = Minimum cut capacity
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              MAX-FLOW MIN-CUT DUALITY                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚      β”Œβ”€β”€β”€β”€β”€  5  ─────┐                                          β”‚
β”‚      β”‚               β”‚                                          β”‚
β”‚   S ────── 10 ───────┼── T                                      β”‚
β”‚      β”‚               β”‚                                          β”‚
β”‚      └─────  3  β”€β”€β”€β”€β”€β”˜                                          β”‚
β”‚                                                                 β”‚
β”‚  Max flow = 18 (5 + 10 + 3)                                     β”‚
β”‚  Min cut = 18 (cut all edges between S and T)                   β”‚
β”‚                                                                 β”‚
β”‚  More complex example:                                          β”‚
β”‚         β”Œβ”€β”€β”€ 10 ──→ B ─── 10 ──┐                                β”‚
β”‚         β”‚           β”‚          β”‚                                β”‚
β”‚      S ──           5          β”œβ”€β†’ T                            β”‚
β”‚         β”‚           ↓          β”‚                                β”‚
β”‚         └─── 10 ──→ C ─── 10 β”€β”€β”˜                                β”‚
β”‚                                                                 β”‚
│  Bottleneck is edge B→C (capacity 5)                            │
β”‚  Max flow = 15 (10 through B, 5 can cross to C, + 10 through C) β”‚
│  Actually: S→B→T: 10, S→C→T: 10, blocked by B-C                 │
│  Min cut = {B→C, one of S edges} but optimally just 15          │
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Finding the Min-Cut

After max-flow, perform BFS from source on residual graph:

JAVA(33 lines)
Code
Loading syntax highlighter...

πŸ”¬ Deep Dive: Bipartite Matching

Maximum Bipartite Matching

Find the largest set of edges with no shared vertices:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              BIPARTITE MATCHING                                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  Workers        Jobs           Matching                         β”‚
β”‚                                                                 β”‚
β”‚    A ─────────── 1              A ═══════ 1                     β”‚
β”‚    β”‚  β•²                         β”‚                               β”‚
β”‚    β”‚   β•²                        β”‚                               β”‚
β”‚    B ───╲─────── 2              B ═══════ 2                     β”‚
β”‚    β”‚     β•²   β•±                                                  β”‚
β”‚    β”‚      β•² β•±                                                   β”‚
β”‚    C ──────╳──── 3              C ═══════ 3                     β”‚
β”‚            β•²                                                    β”‚
β”‚             β•²                                                   β”‚
β”‚    D ────────╲── 4              D (unmatched)                   β”‚
β”‚                                                                 β”‚
β”‚  Maximum matching = 3                                           β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Hungarian Algorithm (Kuhn's Algorithm)

JAVA(58 lines)
Code
Loading syntax highlighter...
Augmenting path intuition:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              AUGMENTING PATH IN MATCHING                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  Current matching: A-1, B-2                                     β”‚
β”‚  C wants to match but only connects to 1 and 2                  β”‚
β”‚                                                                 β”‚
β”‚    A ═══════ 1       Try Cβ†’1: 1 matched to A                    β”‚
β”‚              β”‚       Can A find alternative?                    β”‚
β”‚    B ═══════ 2       Aβ†’2: 2 matched to B                        β”‚
β”‚              β”‚       Can B find alternative?                    β”‚
β”‚    C ──────→ 1,2     Bβ†’3: 3 unmatched! Success!                 β”‚
β”‚              β”‚                                                  β”‚
β”‚    (unmatched) 3     New matching: A-2, B-3, C-1                β”‚
β”‚                                                                 β”‚
β”‚  Augmenting path: C β†’ 1 β†’ A β†’ 2 β†’ B β†’ 3                         β”‚
β”‚  (alternating unmatched, matched, unmatched, matched, unmatch)  β”‚ 
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Reducing to Max-Flow

Bipartite matching can be solved as max-flow:

JAVA(29 lines)
Code
Loading syntax highlighter...

Hopcroft-Karp Algorithm

For better complexity O(E√V):

JAVA(96 lines)
Code
Loading syntax highlighter...

⚠️ Common Mistakes

JAVA(9 lines)
Code
Loading syntax highlighter...
Why: Back edge target might have updated its low-link through a different path.

Mistake 2: Missing Reverse Edges in Flow

JAVA(14 lines)
Code
Loading syntax highlighter...

Mistake 3: Articulation Point Root Check

JAVA(9 lines)
Code
Loading syntax highlighter...
Why: Non-root vertices use the low-link condition, not children count.

Mistake 4: Visited Array in Bipartite Matching

JAVA(11 lines)
Code
Loading syntax highlighter...

πŸ› Debug This: SCC with Incorrect DFS Ordering

This Tarjan's SCC implementation has a subtle bug. Can you find it?

JAVA(54 lines)
Code
Loading syntax highlighter...
πŸ” Click to reveal the bug
Bug: In the back edge case, using lowLinks[neighbor] instead of ids[neighbor].
JAVA(9 lines)
Code
Loading syntax highlighter...
Why this matters:
Consider graph: 0 β†’ 1 β†’ 2 β†’ 0

DFS from 0:
  Visit 0: id=0, low=0, stack=[0]
  Visit 1: id=1, low=1, stack=[0,1]
  Visit 2: id=2, low=2, stack=[0,1,2]
    Back edge 2β†’0:
      With bug: low[2] = min(2, low[0]) = min(2, 0) = 0 βœ“
      Actually works here, but...

Consider: 0 β†’ 1 β†’ 2 β†’ 1 (where 2β†’1 is back edge)

With correct algorithm, when we see back edge 2β†’1:
  low[2] = min(low[2], id[1]) = min(2, 1) = 1

But if low[1] was updated before we return:
  The buggy version might use an outdated low[1]

The fix ensures we always reference the stable discovery time, not the potentially-changing low-link value.


πŸ’» Exercises

Exercise 1: Find All SCCs ⭐⭐

Implement both Kosaraju's and Tarjan's algorithms and verify they produce the same SCCs.

JAVA(6 lines)
Code
Loading syntax highlighter...
Test case:
Vertices: 8
Edges: 0β†’1, 1β†’2, 2β†’0, 2β†’3, 3β†’4, 4β†’5, 5β†’3, 6β†’5, 6β†’7, 7β†’6
Expected SCCs: {0,1,2}, {3,4,5}, {6,7}

Exercise 2: Critical Infrastructure ⭐⭐

Given a network of servers and connections, find:

  1. All articulation points (critical servers)
  2. All bridges (critical connections)
JAVA(10 lines)
Code
Loading syntax highlighter...

Exercise 3: Maximum Flow with Multiple Sources ⭐⭐⭐

Modify Edmonds-Karp to handle multiple sources and sinks.

JAVA(6 lines)
Code
Loading syntax highlighter...

Exercise 4: Job Assignment Problem ⭐⭐⭐

Given N workers and M jobs, where worker i can do jobs in skills[i], find maximum number of jobs that can be completed (each worker does at most one job).
JAVA(9 lines)
Code
Loading syntax highlighter...

Exercise 5: Minimum Vertex Cover ⭐⭐⭐⭐

In a bipartite graph, find the minimum set of vertices that covers all edges. Use KΓΆnig's theorem: minimum vertex cover = maximum matching.

JAVA(7 lines)
Code
Loading syntax highlighter...
Hint: After finding max matching:
  • Start BFS from unmatched left vertices
  • Alternating between unmatched and matched edges
  • Minimum vertex cover = (matched left not reached) βˆͺ (right reached)

🎀 Interview Questions

Q1: "When would you use Tarjan's vs Kosaraju's SCC algorithm?"

Answer: Both have O(V+E) complexity, but differ in practice:
Tarjan's:
  • Single DFS pass
  • Lower constant factors
  • More complex to implement correctly
  • Outputs SCCs in reverse topological order
Kosaraju's:
  • Two DFS passes (original + reversed graph)
  • Easier to understand and implement
  • Requires building reverse graph (extra O(V+E) space)
  • More intuitive proof of correctness
Choose Tarjan's when: memory is constrained, or you need the algorithm in competitive programming.
Choose Kosaraju's when: clarity is important, or you're teaching/explaining SCCs.

Q2: "Explain the max-flow min-cut theorem and a practical application."

Answer: The theorem states that in any flow network, the maximum flow from source to sink equals the minimum capacity of any cut separating source from sink.
Intuition:
  • Maximum flow is limited by some bottleneck
  • That bottleneck is exactly the minimum cut
Practical application - Image Segmentation:
Problem: Separate foreground from background in image

Model:
- Each pixel is a vertex
- Source connects to "definitely foreground" pixels (∞ capacity)
- Sink connects to "definitely background" pixels (∞ capacity)
- Adjacent pixels connected with capacity = similarity

Min-cut finds optimal boundary between foreground/background
(minimizes cutting through similar pixels)

Q3: "How would you find if a graph has a unique topological ordering?"

Answer: A DAG has a unique topological ordering if and only if there's a Hamiltonian path (path visiting all vertices exactly once).
Algorithm:
JAVA(26 lines)
Code
Loading syntax highlighter...

Q4: "Design a system to match drivers to riders optimally."

Answer: This is a bipartite matching problem with weights (Hungarian algorithm for minimum cost).
JAVA(31 lines)
Code
Loading syntax highlighter...
Considerations:
  • Real-time updates as drivers/riders appear
  • Batch matching every few seconds
  • Consider fairness (don't always assign closest)

Q5: "What's the relationship between articulation points and 2-edge-connected components?"

Answer:
Articulation points split the graph into biconnected components (2-vertex-connected). Bridges split the graph into 2-edge-connected components.
2-vertex-connected: Remains connected after removing any single vertex
2-edge-connected: Remains connected after removing any single edge

Relationship:
- Every bridge's endpoints are articulation points (unless degree 1)
- Articulation point doesn't always imply bridge exists

Example:
    A --- B
    |  X  |     (X marks diagonal edges)
    C --- D

No bridges (every edge is in a cycle)
No articulation points (2-vertex-connected)

vs:

    A --- B --- E
    |     |
    C --- D

B is articulation point
B-E is a bridge

πŸ“‹ Quick Reference

Algorithm Complexity

AlgorithmTimeSpaceUse Case
Kosaraju's SCCO(V+E)O(V+E)Find strongly connected components
Tarjan's SCCO(V+E)O(V)Find SCCs, single pass
Articulation PointsO(V+E)O(V)Find critical vertices
BridgesO(V+E)O(V)Find critical edges
Ford-FulkersonO(E Γ— max_flow)O(VΒ²)Max flow (integer capacities)
Edmonds-KarpO(VEΒ²)O(VΒ²)Max flow (polynomial)
HungarianO(VΒ³)O(VΒ²)Min cost bipartite matching
Hopcroft-KarpO(E√V)O(V)Max bipartite matching

Key Formulas

SCC Root Condition:     ids[v] == lowLinks[v]
Articulation (root):    children > 1
Articulation (non-root): lowLinks[child] >= ids[v]
Bridge Condition:       lowLinks[v] > ids[parent]
Max-Flow = Min-Cut:     Always true (duality theorem)
KΓΆnig's Theorem:        Min Vertex Cover = Max Matching (bipartite)

Code Templates

JAVA(14 lines)
Code
Loading syntax highlighter...

πŸ”— What's Next?

In Part 15: Graph Algorithms in Practice, we'll explore:
  • Social network analysis
  • Recommendation systems
  • PageRank algorithm
  • Community detection
  • Real-world case studies

πŸ“… Review Schedule

DayFocusTime
0Full read + exercises90 min
1Quick Reference + SCCs10 min
3Implement Tarjan's from memory20 min
7Max-flow problem15 min
14Debug exercise + bipartite matching15 min
30All interview questions10 min