Graphs §
Graphs model arbitrary connectivity between entities: social networks, road maps, dependency graphs, circuits. They are relevant whenever the relationship between items is not a simple hierarchy or key-value mapping but an arbitrary set of edges.
The generalization chain is: a tree is a connected acyclic graph; a DAG (directed acyclic graph) generalizes a tree by allowing multiple parents; a general graph allows arbitrary cycles and multi-edges. Every structure that is a tree or DAG is also a graph, so graph algorithms subsume tree and DAG algorithms.
Authoritative sources
Definitions §
A graph has a set of vertices and a set of edges .
- Directed (digraph): each edge is an ordered pair , written . The edge does not imply .
- Undirected: each edge is an unordered pair , written . The edge is the same as .
- Weighted: each edge carries a numeric weight (or possibly negative).
- Simple: no self-loops, no parallel (multi-)edges.
- DAG: a directed graph with no directed cycles.
Every algorithm below behaves differently for directed vs. undirected graphs: topological sort applies only to DAGs, cycle detection differs (back edges in DFS for directed; any non-tree edge for undirected), and MST is defined only for undirected graphs.
Representation §
A graph with , :
| Representation | Space | Edge query | Iterate neighbors |
|---|---|---|---|
| Adjacency list | O(n + m) | O(deg(v)) | O(deg(v)) |
| Adjacency matrix | O(n2) | O(1) | O(n) |
| Hash set of edges | O(n + m) | O(1) expected | O(deg(v)) |
Details
Adjacency list: an array of lists (or vectors). Best for sparse graphs (). The standard choice for most algorithms. Each list is a List structure.
Adjacency matrix: a 2D boolean array. Best for dense graphs or when edge queries are frequent. Supports fast matrix multiplication for transitive closure: the naive algorithm is ; Strassen’s divide-and-conquer gives ; the best-known algorithms achieve with .
Edge list: a flat array of (u, v, weight) tuples. Compact, good for external-memory algorithms and GPU parallelism.
Complexity context: the Big-O bounds above are analyzed in the framework of Computability and Complexity Classes, which defines time and space complexity and complexity classes.
Traversal: BFS and DFS §
BFS (Breadth-First Search): explore level by level using a queue.
- Time: .
- Finds: shortest paths in unweighted graphs, connected components, cycle detection (in undirected graphs).
DFS (Depth-First Search): explore as deep as possible using a stack (or recursion).
- Time: .
- Finds: connected components, cycle detection, topological order, articulation points, biconnected components.
Details
BFS: maintain a queue. Start from source , mark visited, enqueue neighbors. The first time a vertex is dequeued, the path to it is shortest (in edge count).
Worked example — BFS on a 6-node graph:
Consider the undirected graph with edges: 0-1, 0-2, 1-3, 2-4, 3-4, 4-5. Start from node 0.
| Step | Dequeue | Queue (front→back) | Visited | Distances |
|---|---|---|---|---|
| 0 | — | [0] | {0} | d(0)=0 |
| 1 | 0 | [1, 2] | {0,1,2} | d(1)=1, d(2)=1 |
| 2 | 1 | [2, 3] | {0,1,2,3} | d(3)=2 |
| 3 | 2 | [3, 4] | {0,1,2,3,4} | d(4)=2 |
| 4 | 3 | [4] | {0,1,2,3,4} | (4 already visited) |
| 5 | 4 | [5] | {0,1,2,3,4,5} | d(5)=3 |
| 6 | 5 | [] | {0,1,2,3,4,5} | (done) |
The BFS levels are:
DFS: maintain a stack (or call stack). Three states per vertex: white (unvisited), gray (in progress), black (done). A back edge (to a gray vertex) indicates a cycle in a directed graph; in an undirected graph, any edge to an already-visited vertex that is not the parent indicates a cycle.
Topological sort (Kahn’s algorithm): repeatedly remove vertices with in-degree 0. . Fails (detects a cycle) if not all vertices are removed. Used in build systems (make, Bazel), dependency resolution (npm, cargo), and course scheduling.
Interactive visualization: see the Graphs simulation for animated BFS, DFS, and Dijkstra.
Shortest paths §
Dijkstra’s algorithm: single-source shortest paths in graphs with non-negative edge weights.
- Time: with a binary heap ( per extract-min and decrease-key).
- Correctness: greedy — the vertex with the smallest tentative distance is finalized.
Bellman-Ford: handles negative weights (but not negative cycles).
- Time: .
A*: Dijkstra + a heuristic .
- Time: in the worst case, but much faster in practice when is informative.
- Optimality: A* is optimal when is admissible: for all , where is the true shortest distance from to the target .
- Efficiency: if is additionally consistent (a.k.a. monotone): for every edge $(u,v)$, then each node is expanded at most once, and the algorithm terminates without re-opening nodes. Consistency implies admissibility.
Details
Dijkstra: maintain a priority queue of (distance, vertex). Pop the minimum, relax its outgoing edges. Each vertex is finalized once. The binary heap gives per extract-min and per decrease-key.
Worked example — Dijkstra on a 5-node weighted graph:
Edges: A→B (4), A→C (2), B→C (1), B→D (5), C→D (8), C→E (10), D→E (2). Source: A.
| Iteration | Extract-min | Relax edges | PQ state (dist, node) |
|---|---|---|---|
| 1 | A (0) | A→B: d(B)=4; A→C: d(C)=2 | [(2,C), (4,B)] |
| 2 | C (2) | C→D: d(D)=10; C→E: d(E)=12; C→B: 2+1=3 < 4 → d(B)=3 | [(3,B), (10,D), (12,E)] |
| 3 | B (3) | B→D: 3+5=8 < 10 → d(D)=8; B→C: already finalized | [(8,D), (12,E)] |
| 4 | D (8) | D→E: 8+2=10 < 12 → d(E)=10 | [(10,E)] |
| 5 | E (10) | (no outgoing edges) | [] |
Shortest distances from A: d(A)=0, d(B)=3, d(C)=2, d(D)=8, d(E)=10.
Floyd-Warshall: all-pairs shortest paths in . Dynamic programming over the set of allowed intermediate vertices.
A*: the heuristic estimates the remaining cost to the target. In a grid, Manhattan distance is admissible. In a road network, the crow-fly (Euclidean) distance is admissible. A* is the basis of GPS navigation and game pathfinding.
See also Learning Paradigms and Models for the RL framing of shortest-path problems.
Minimum spanning trees §
An MST of a weighted connected undirected graph is a tree spanning all vertices with minimum total edge weight.
Kruskal’s algorithm: sort edges by weight; add an edge if it doesn’t form a cycle (union-find).
- Time: .
Prim’s algorithm: grow the tree from a root; at each step, add the cheapest edge crossing the cut.
- Time: with a binary heap.
Details
Union-Find (disjoint set union): supports make-set, find, union in amortized per operation (inverse Ackermann, effectively constant). Path compression + union by rank.
Cut property: for any cut of the graph, the minimum-weight edge crossing the cut is in some MST. Both Kruskal and Prim exploit this property.
Worked example — Kruskal on a 6-node weighted graph:
Edges (sorted by weight): AB(1), BC(2), CD(3), DE(4), EF(5), AC(6), BE(7), DF(8).
| Step | Edge considered | Weight | Union-Find sets | Action |
|---|---|---|---|---|
| 1 | AB | 1 | {A,B}, {C}, {D}, {E}, {F} | Add (no cycle) |
| 2 | BC | 2 | {A,B,C}, {D}, {E}, {F} | Add (no cycle) |
| 3 | CD | 3 | {A,B,C,D}, {E}, {F} | Add (no cycle) |
| 4 | DE | 4 | {A,B,C,D,E}, {F} | Add (no cycle) |
| 5 | EF | 5 | {A,B,C,D,E,F} | Add (no cycle) |
| 6 | AC | 6 | {A,B,C,D,E,F} | Skip (cycle) |
| 7 | BE | 7 | {A,B,C,D,E,F} | Skip (cycle) |
| 8 | DF | 8 | {A,B,C,D,E,F} | Skip (cycle) |
MST edges: AB, BC, CD, DE, EF. Total weight: 1+2+3+4+5 = 15.
Applications: network design (minimize cable length), clustering (single-linkage), image segmentation (minimum spanning tree of a pixel graph), and approximation algorithms (Christofides: MST gives a 1.5-approximation for TSP).
Network flows §
A flow network is a directed graph with a source , a sink , and a capacity on each edge. A flow assigns a value to each edge such that:
- Capacity constraint: .
- Flow conservation: for every vertex , the inflow equals the outflow: .
The max-flow problem finds the maximum value of flow from to .
Ford-Fulkerson method: repeatedly find an augmenting path in the residual graph and push flow along it.
- Time: where is the max flow value (pseudo-polynomial; can be slow with irrational capacities).
Edmonds-Karp: Ford-Fulkerson with BFS to find the shortest augmenting path.
- Time: (polynomial).
Max-flow min-cut theorem: the maximum flow value equals the minimum cut capacity. A cut $(S, T)$ partitions vertices with , ; its capacity is $\sum_{u \in S, v \in T} c(u,v)$.
Details
Residual graph: after pushing flow, the residual graph has forward edges with residual capacity and backward edges with capacity (allowing “undo”). An augmenting path is any path in the residual graph.
Worked example — Ford-Fulkerson on a small network:
Nodes: s, a, b, t. Edges and capacities: s→a (3), s→b (2), a→b (1), a→t (2), b→t (3).
| Iteration | Augmenting path | Bottleneck | Flow pushed | Residual capacities |
|---|---|---|---|---|
| 1 | s→a→t | min(3,2)=2 | 2 | s→a:1, a→t:0, s→b:2, a→b:1, b→t:3 |
| 2 | s→b→t | min(2,3)=2 | 2 | s→a:1, s→b:0, a→b:1, b→t:1 |
| 3 | s→a→b→t | min(1,1,1)=1 | 1 | s→a:0, a→b:0, b→t:0 |
No more augmenting paths exist. Max flow = 2 + 2 + 1 = 5.
The min cut is , : capacity = c(a,t) + c(b,t) = 2 + 3 = 5. ✓
Applications:
- Bipartite matching: reduce to max-flow by adding a source connected to the left partition and a sink from the right partition, all with capacity 1.
- Image segmentation: the min-cut of a graph whose nodes are pixels and whose edge weights encode color similarity separates foreground from background (graph cuts).
- Project scheduling: the critical path in a project network is the longest path; the dual (min-cut) identifies the set of tasks whose delay would extend the project.
- Transportation: maximize throughput in a road or pipe network.
Graph properties §
Several structural properties classify a graph and determine which algorithms apply:
| Property | Definition | Typical application |
|---|---|---|
| Bipartite | Vertices split into two sets; every edge crosses between sets (no odd cycle) | Scheduling, matching, map coloring (2-color) |
| Planar | Can be drawn in the plane with no edge crossings | Circuit routing, map coloring (4-color theorem), VLSI layout |
| Eulerian | Has a cycle that uses every edge exactly once (all vertices have even degree) | Route inspection (postal routes), network design |
| Hamiltonian | Has a cycle that visits every vertex exactly once | TSP, circuit design, scheduling |
- Bipartite detection: BFS 2-coloring in . If any edge connects two vertices of the same color, the graph is not bipartite.
- Planarity: tested in time (Hopcroft–Tarjan). The 4-color theorem guarantees every planar graph is vertex-4-colorable.
- Eulerian: check that the graph is connected and every vertex has even degree (undirected) or in-degree = out-degree (directed).
- Hamiltonian: NP-complete in general; no known polynomial-time algorithm.
Quizz §
Problem: Given a directed graph with 500 nodes and 2000 weighted edges (all weights positive), find the shortest path from node 1 to node 500. Which algorithm do you choose and why?
Solution
Choice: Dijkstra’s algorithm with a binary heap.
Reasoning:
- All weights are positive → Dijkstra applies (Bellman-Ford is unnecessary).
- The graph is sparse: → adjacency list representation.
- Time: operations.
- A* would be faster in practice if a good admissible heuristic is available (e.g., geographic distance for a road network), but without domain-specific structure, Dijkstra is the safe default.
- Floyd-Warshall () is overkill for a single-source query.
If weights could be negative: switch to Bellman-Ford, operations.
If the graph were undirected and unweighted: BFS in operations.