A Systematic Approach to Algorithms

Vijay K. Garg · The University of Texas at Austin

Chapter 6. Graphs

Classical sequential graph traversals (BFS, DFS) and layering.

This page: Classical forms. View LLP forms »

This page collects the classical / sequential implementations of the algorithms developed in this chapter. The lattice-linear (LLP) reformulations and chapter setup live on the LLP companion page.

Sequential traversals

A graph traversal visits every vertex reachable from a given source. The two standard strategies differ only in the order they explore neighbors:

Both run in $O(n + m)$ time on an adjacency-list representation.

Layering a directed acyclic graph

Given a DAG, layering assigns each vertex $v$ to layer $\ell(v) = $ length of the longest path from any source to $v$. Sources (in-degree zero) sit on layer 0. The classical algorithm maintains an in-degree counter for every vertex, enqueues all sources, and peels them off one layer at a time: when a vertex is removed, its successors' in-degrees are decremented, and any that reach zero are enqueued for the next layer. This is essentially a topological sort that additionally tracks the layer number. It runs in $O(n + m)$ time.

Strongly connected components (Kosaraju)

A strongly connected component (SCC) of a directed graph is a maximal set of vertices such that every vertex is reachable from every other. Kosaraju's algorithm finds all SCCs in two passes of DFS:

  1. Run DFS on the original graph and push each vertex onto a stack in order of decreasing finish time.
  2. Pop vertices from the stack one at a time. For each unvisited vertex, run DFS on the transpose graph (all edges reversed); the set of vertices visited in that DFS forms one SCC.

Both passes run in $O(n + m)$ time, so the total cost is $O(n + m)$.

Traversal

Generic queue-based reachability from vertex 0; matches the book's "removeAny" sequential traversal. Returns $G[i] = 1$ iff $v_i$ is reachable.

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

BFS

FIFO-queue BFS distance computation. Sets $G[i] = $ shortest-edge-count distance from source $s$, or Integer.MAX_VALUE if unreachable.

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

DFS

Recursive DFS recording discovery and finish times. parent[] records the DFS-tree parent (-1 for the root); a 1-element array t rides on the recursion to share the global tick counter.

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

Layering

The classical in-degree-zero queue version of layering. Computes $G[j] = $ length of the longest path from any source vertex to $j$.

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