Definition · Discovery and finish timesA depth-first walk of a digraph keeps a counter starting at 0. On reaching an undiscovered vertex v it increments the counter and records d[v]; after every arc out of v has been considered it increments the counter again and records f[v]. When the walk from one root runs out of reachable vertices it restarts at the lowest-numbered undiscovered vertex, so the tree arcs form a FOREST and not necessarily a tree.
The counter is shared across the whole forest, which is what makes the times comparable between vertices that were never on the same walk. On n vertices it ends at 2n, always, because each vertex contributes exactly one tick when it opens and one when it closes.
Definition · The four classes of an arcRelative to one completed walk, an arc (u, v) is a tree arc if v was discovered by it; a back arc if v is a proper ancestor of u in the forest; a forward arc if v is a proper descendant of u and the arc is not the tree arc; and a cross arc otherwise. The four are exhaustive and exclusive, so every arc gets exactly one label.
The definition names ancestry, and ancestry is read off the times: v is a descendant of u exactly when d[u] < d[v] and f[v] < f[u]. That is the whole of the implementation. The lab prints, for every arc, the class and the comparison that settled it.
Example · Eight arcs, one walk, all four classesThe lab opens on the arcs 1>2, 1>4, 2>5, 4>2, 5>4, 3>5, 3>6, 6>3 with the walk starting at 1. The walk goes 1, 2, 5, 4, closes all four, then restarts at 3 and reaches 6, giving d = 1, 2, 9, 4, 3, 10 and f = 8, 7, 12, 5, 6, 11. Classified from those numbers: 1>2, 2>5, 5>4 and 3>6 are tree arcs; 4>2 and 6>3 are back; 1>4 is forward, because 4 is a finished descendant of 1; and 3>5 is cross, because [9, 12] and [3, 6] do not meet. Four, two, one and one, on eight arcs.
Two of those deserve a second look. 1>4 is forward rather than tree because the walk reached 4 first through 2 and 5 — the arc 1>4 was examined later, found 4 already finished, and discovered nothing. And 3>5 is cross although 3 and 5 are both on the same picture: the walk had closed 5 at step 6 before it opened 3 at step 9, so neither is an ancestor of the other.
Theorem · The parenthesis theoremFor any two vertices u and v of one walk, exactly one of three things holds: the intervals [d[u], f[u]] and [d[v], f[v]] are disjoint and neither vertex is an ancestor of the other; [d[v], f[v]] lies wholly inside [d[u], f[u]] and v is a descendant of u; or the reverse. The intervals never partly overlap.
Suppose d[u] < d[v]. When v is discovered, u is either still open or already closed.
If u is still open then the walk reached v from inside u, so v is a descendant of u; and the walk cannot close u while v is open, because closing u means every arc out of it, and every recursive call below it, has returned. So f[v] < f[u] and the intervals nest.
If u is already closed then f[u] < d[v], so the intervals are disjoint, and neither can be an ancestor of the other: an ancestor is open for the whole of its descendant's interval. A partial overlap would need d[u] < d[v] < f[u] < f[v], which is the first case with v closing after u, and that case has just been ruled out.
□
The lab does not quote that theorem, it checks it. On the opening graph there are 15 pairs of vertices; the panel reports that 7 of them nest, 8 are disjoint, and 0 overlap without nesting, and it separately confirms that nesting and descent agree on every pair. Change the graph and it recounts.
The class of an arc is a fact about the walk, not about the graph
Start the same eight arcs at vertex 3 instead of vertex 1. The times become d = 11, 4, 1, 3, 2, 8 and f = 12, 5, 10, 6, 7, 9, and the counts change: four tree arcs and two back arcs as before, but now 0 forward arcs and 2 cross arcs. The arc 1>4 that was forward is now cross. Move the slider in the lab and watch the table rewrite itself.
What does NOT change is the back count. It is 2 from either root, and it has to be: a back arc means a cycle, a cycle is a property of the arcs and not of the walk, and this graph has cycles. The lab's status line therefore reads acyclicity off the back count alone and says nothing about the other three.
Read the same arcs undirected and two classes disappear
Switch the lab's reading to undirected and the counts for forward and cross both come out 0, on this graph and on every graph the panel has been given. The reason is that an undirected edge is met from whichever end the walk reached first: if the far end is already discovered it cannot have been finished, because the walk would have crossed this very edge and finished this end first. So the far end is an open ancestor, which is a back edge. Forward and cross are phenomena of direction.
Finally the cost. On the opening graph the panel reports 6 vertex visits and 8 arc reads, and those two numbers are what Θ(V + E) names: each vertex is opened once and each arc is examined once from its tail. The count is for this graph. The bound is the claim that on every graph the two figures are exactly V and E, and it is proved by the walk's own structure — a vertex is discovered once because discovery sets d, and an arc is read once because the loop over a vertex's arcs runs once.