A Systematic Approach to Algorithms

Vijay K. Garg · The University of Texas at Austin

Chapter 6. Graphs

Reachability, distance, and layering as LLP fixed-points on vertex vectors.

This page: LLP forms. View classical forms »

Setting

A directed graph $G = (V, E)$ has $n$ vertices $v_0, v_1, \ldots, v_{n-1}$ and $m$ edges. Each edge $(i, j) \in E$ goes from $i$ to $j$. The neighbors of a vertex $j$ split into its predecessors $\text{pre}(j) = \{ i \mid (i, j) \in E \}$ and its successors $\text{succ}(j) = \{ k \mid (j, k) \in E \}$. The book covers two storage formats: the $n \times n$ adjacency matrix (constant-time edge lookup, $O(n^2)$ space) and the adjacency list (one linked list of neighbors per vertex, $O(n + m)$ space, sparse-friendly). The demos below use the predecessor-list view because the LLP forbidden conditions are naturally stated over predecessors.

The LLP perspective

The graph problems above all admit the same "forbidden / advance" template introduced in Chapter 2. We pick a state vector $G$, write a predicate $B(G)$ describing feasibility, identify the indices that block $B$, and advance them. Three concrete instances:

All three lattices are finite distributive, so the LLP main loop converges to the unique least fixed point regardless of the order in which forbidden indices are picked. Choosing a priority on $G[j]$ (smallest distance first) recovers the classical BFS schedule; choosing sources first recovers the classical layering algorithm.

LLP-BFS

$G[j]$ is the current upper bound on the BFS distance from $v_0$ to $v_j$. The vector starts at $G = (0, \infty, \infty, \ldots)$. An index $j$ is forbidden when some predecessor $i$ satisfies $G[i] + 1 < G[j]$; the advance rule lowers $G[j]$ to $\min_{i \in \text{pre}(j)} G[i] + 1$. The fixed point is the BFS distance vector.

Time complexity: $O(n + m)$, where $n$ is the number of vertices and $m$ is the number of edges.

LLP-Layering

$G[j]$ is the current layer of vertex $j$ and $\text{fixed}[j]$ records whether the layer has been finalized. Initially $G[j] = 0$ for every $j$, $\text{fixed}[j] = \text{true}$ for sources, and $\text{fixed}[j] = \text{false}$ otherwise. An index $j$ is forbidden when it is not yet fixed but all of its predecessors are; the advance rule sets $G[j] := 1 + \max_{i \in \text{pre}(j)} G[i]$ and marks $j$ fixed. The default input is the DAG of the book's worked example (vertices $v_0, \ldots, v_5$ with $v_0, v_1$ as sources and longest path $v_0 \to v_3 \to v_4 \to v_5$).

Time complexity: $O(n + m)$, where $n$ is the number of vertices and $m$ is the number of edges.

LLP-Traversal

Reachability as a 1-bit lattice: $G[j] = 1$ iff vertex $j$ is reachable from the source. Forbidden: some predecessor is reached but $j$ is not. Advance: mark $j$ reached.

Time complexity: $O(n + m)$, where $n$ is the number of vertices and $m$ is the number of edges.

void LLPTraversal(set<int>[] pre, boolean[] G) {
  forbidden (j) : !G[j] && (exists i in pre[j] : G[i])  =>
    advance : G[j] = true;
}

LLP predicates for this chapter

Each LLP program in this chapter defines a state vector $G$ and a forbidden predicate; the algorithm runs until no $j$ is forbidden. The table below lists, for each algorithm, what $G[i]$ represents and the negation of the forbidden clause from the matching .llp source.

Algorithm $G[j]$ Negation of the forbidden clause
LLP-BFS $G[j]$ — BFS distance to vertex $j$ $\forall j:\ G[j] \leq \min_{i \in \mathrm{pre}(j)} (G[i] + 1)$
LLP-Layering $G[j]$ — layer of vertex $j$ $\forall j:\ \mathrm{fixed}[j] \,\vee\, \bigl(\exists\, i \in \mathrm{pre}(j):\ \neg\,\mathrm{fixed}[i]\bigr)$
LLP-Traversal $G[j]$ — vertex $j$ has been reached $\forall j:\ G[j] \,\vee\, \bigl(\forall\, i \in \mathrm{pre}(j):\ \neg G[i]\bigr)$
SlowComponents (ensure) $G[j]$ — component label of vertex $j$ $\forall j:\ G[j] \geq \max_{i \in \mathrm{adj}(j)} G[i]$