An infinite trace exists exactly when a directed cycle is reachable from , by the infinite walk criterion in a finite directed graph. Compute the reachable set with depth-first search, compute its strongly connected components, and return true if any component has at least two vertices or contains a self-loop. A singleton without a self-loop does not qualify.
If the test succeeds, follow a path from to the cycle and traverse the cycle forever. Conversely, an infinite trace in a finite graph repeats a vertex, producing a reachable nonempty closed walk and hence a directed cycle. Reachability, component construction and the self-loop check all scan adjacency lists only a constant number of times. The worst-case time is , with auxiliary space for a straightforward transpose-based implementation.
Maintain white, gray and black colors for undiscovered, active and completed vertices. A single traversal clock records DFS discovery and finishing times:
for v in V: color[v] = white; parent[v] = none
time = 0
visit(u):
    time = time+1; d[u] = time; color[u] = gray
    for v in adjacency[u]:
        if color[v] == white:
            parent[v] = u
            visit(v)
    color[u] = black; time = time+1; f[u] = time
for u in V:
    if color[u] == white: visit(u)
The outer loop makes a depth-first search forest even when the directed graph is disconnected. Each vertex is entered once and each directed adjacency entry is inspected once. Thus an adjacency list representation gives time and auxiliary storage, including the worst-case recursive stack. Sorting neighbors to impose a particular visit order would be additional work.
False. Use vertices , edges , , , and start depth-first search at , scanning before . The times are
There is a directed path and , but and are separate children of . Thus is not a descendant of . The path leaves through an already gray ancestor; its later branch need not be explored inside 's recursive call. This is consistent with the DFS parenthesis property.
Figure 1.
DFS counterexamples distinguish reachability from tree ancestry
. Left: the path from u through its ancestor x reaches a later sibling v, after u has finished. Right: root order a,u,c makes three singleton DFS trees, though u has an incoming and an outgoing edge. Details.
In depth-first search, mark every vertex white initially. At a white start vertex , increment a global clock, record and color it gray. Scan its outgoing adjacency list; recursively visit each still-white neighbor, recording the discovery edge. After all neighbors have been processed, color black, increment the clock and record . Start again from every remaining white vertex to obtain a forest. Each vertex is discovered once and each edge scanned once, so the time is with adjacency lists.
The DFS parenthesis property says that for distinct vertices , their intervals and are disjoint or one lies strictly inside the other. Moreover is a proper descendant in a rooted tree of exactly when . A recursive call finishes before its caller returns, while completed calls from separate branches have disjoint intervals; these two possibilities prove the property.
False. Let the directed edges be , , and . Start depth-first search at and explore its neighbor before . Then
The directed path exists and , but and are siblings in the discovery tree. An existing path may leave the current recursive branch via a gray ancestor and only later enter a different branch. The usual white-path condition would need all vertices of a suitable path to be white when is discovered; that condition is absent here.
Figure 1.
A directed path crosses from an earlier DFS branch to a later branch through the root; node labels give discovery and finishing times
. Details.
False. Use only the directed edge , but choose first in the outer loop of depth-first search. It finishes before a second discovery tree starts at : , , , . The edge supplies the required directed path and , yet . A path to an already black vertex need not put the two vertices into one discovery tree.
False. Take two vertices with both directed edges, and start depth-first search at . The timestamps are , , , . There is an edge, hence a directed path, from to , but . Reaching a gray ancestor does not make the ancestor finish first.
Use breadth-first search with the supplied FIFO queue, taking one edge to mean one permitted prefix reversal:
def solve(puzzle: Flip): Flip = {
  val pending = scala.collection.mutable.Queue[Flip]()
  pending.enqueue(puzzle)
  while (!pending.isEmpty) {
    val current = pending.dequeue()
    if (current.isIdentity) return current
    var k = 2L
    while (k <= current.game.length.toLong) {
      pending.enqueue(current.flip(k.toInt))
      k += 1L
    }
  }
  throw new IllegalStateException("No solution")
}

val puzzle = new Flip(n)
println("Solving:")
println(puzzle)
val answer = solve(puzzle)
println("Solved:")
println(answer)
The FIFO queue holds pending paths in nondecreasing history length. Initially it holds only the zero-move path. Removing a path at depth and appending its children at depth preserves that order. The inner loop invariant says that precisely moves of the removed state have been appended; its loop variant is while the guard holds. The first identity state removed therefore has the minimum possible number of moves. A stack-based depth-first search does not generally have that property.
Termination does not rely on avoiding repeats in this first version. Every permutation can be sorted by prefix reversal sorting: place the largest misplaced value at the front if necessary, flip it into its final position, and repeat on the shorter prefix. This constructs a route of at most moves. Each search depth has finitely many paths, with at most children per path, so breadth-first search reaches some solution depth after finitely many expansions. This gives a finite bound on remaining expansions before the first solution even though the repeated-state path tree is infinite. The one-element game is already solved. Repeated paths can nevertheless make time and storage enormous; part (e) removes that waste.
Use the two-pass strongly connected component algorithm: first run depth-first search on the original directed graph, then search its graph transpose in decreasing order of the first pass's finishing times. The first-pass order from part (a) is
Reversing the edges gives outgoing adjacency lists
The second pass first visits only . Its next new root is , whose search visits ; later entries already marked by this search are skipped. The next new root is , whose graph transpose neighbours have already been assigned. Therefore the components are
Within the middle component the directed cycle demonstrates mutual reachability. The source edge structure does not provide return paths from or to . More generally, decreasing finish order chooses a remaining component whose graph transpose search cannot escape to another still-unassigned component, so each second-pass tree is exactly one component. This explains the partition rather than merely listing it. The algorithm takes with adjacency lists.[ref]
Run depth-first search on Graph B with the same lexical convention and put each vertex on the front of the output when its search finishes. The finish order is
so the returned topological order is
For example, both edges from point to later entries, the edges from point to and later in the order, and precedes . The construction is valid because in a Directed acyclic graph every edge has : a newly found descendant finishes before its caller, and an already finished neighbour also has a smaller finish time; an active ancestor would instead witness a directed cycle. Thus reversing the finish order puts every prerequisite before its successor. The time is .
The only possibilities are . Vertex reaches all of . In depth-first search, all vertices reachable from an active vertex must have been discovered and finished before its own finishing event, except for active ancestors. None of these four can be an ancestor of , because none can reach . Thus all four are finished before finishes.
Vertex cannot already be finished at that point: its outgoing edge to would have caused to be visited before it could finish. It also cannot be a descendant of , since cannot reach . Therefore is either still undiscovered or an active ancestor. In the first case the only remaining events are discovery and finishing of , giving . In the second case the only remaining event is finishing of , giving .
Both occur. Starting the outer traversal with leaves undiscovered and gives time . Starting with and taking its edge to first makes an ancestor and gives time . The argument does not assume any particular order on the other edges.
Increment a single clock on each discovery and finish, starting with clock zero. Lexicographic depth-first search gives
The first search tree has discovery edges , , . The edge returns to an active ancestor. Once that tree finishes, vertex is a new root whose neighbour is already finished, and vertex is the final root. This accounts for all twelve events in the DFS discovery and finishing times.
Robbins' theorem 2026-10-14
A finite nonempty connected graph whose edges are undirected admits a strong orientation if and only if it has no bridge in a graph. This statement holds for finite multigraphs as well as finite simple graphs; self-loops do not help connect distinct vertices. The single-vertex case is allowed, with length-zero directed paths.[ref]
Necessity comes from the two sides separated by deleting a bridge in a graph: its chosen arrow crosses in only one direction. For sufficiency, the cited constructive proof uses depth-first search to find a cycle in a graph, orients it cyclically, contracts it, and repeats. Undoing the contractions replaces junctions by directed cycles, retaining two-way reachability. Contraction can produce multiple edges, so these must remain distinct. This is a construction outline; the input graph is finite and bridgeless, and remaining edges within contracted pieces can receive arbitrary directions.[ref]
Spreadsheet dependency evaluation Created 2026-10-13 Updated 2026-10-14
Evaluate numeric formula dependencies using depth-first search and memoization, or a topological ordering. Marking active evaluations detects cycles; repeated numerical sweeps need not terminate or determine a unique result.
A spreadsheet dependency graph turns a page of spreadsheet formulas into a plan: compute each prerequisite before the spreadsheet cell that consumes it. This section uses a deliberately small model with explicit cell references, fixed spreadsheet formulas, and deterministic computation from numerical inputs. There are no external data changes or formulas that change their references while running. Within these assumptions, a topological order gives a reproducible answer without repeatedly sweeping the visible grid.
Take two input spreadsheet cells and five spreadsheet formulas:
Spreadsheet cellStored input or spreadsheet formulaInitial valueValue after changing A1 to 5
A13, later 5
A24
B1=A1+A2
B2=2*A1
C1=B1+B2
D1=C1/2
E1=A2^2
Figure 1.
An original spreadsheet dependency graph and a topological order with values before and after one edit
. Details.
Our directed edge convention is prerequisite to consumer: A1 B1 means that B1 reads A1, not the reverse. The seven directed edges are A1 B1, A2 B1, A1 B2, B1 C1, B2 C1, C1 D1, and A2 E1. This spreadsheet dependency graph is a Directed acyclic graph. One topological order is A1,A2,B1,B2,C1,D1,E1; E1 could instead be computed immediately after A2. A topological order constrains prerequisites, not the physical positions of spreadsheet cells.
In that order, the initial arithmetic operations give , , , , and . The spreadsheet formulas define one value per spreadsheet cell: an outline by induction along any topological order shows that every prerequisite already has its uniquely determined value when its consumer is computed. Different permitted orders therefore agree in this model. The useful idea is that information flows through the Directed acyclic graph even when the visible grid does not display that flow.
A concrete implementation history illustrates this separation. Microsoft's documentation distinguishes the per-worksheet calculation chains used in Excel 2002 and earlier from calculation using multiple software threads introduced in Excel 2007 for independent chain sections. This is a documented implementation example, not a definition of spreadsheet dependency evaluation.[ref]
The directed graph whose vertices are the spreadsheet cells and whose directed edges mean that the spreadsheet formula in references . Input spreadsheet cells have no prerequisites in this model. Retain both incoming references and outgoing consumers: depth-first search for evaluation follows incoming references backwards, whereas downstream invalidation follows outgoing consumers forwards. A directed path then expresses indirect dependence, and a directed cycle expresses a spreadsheet circular reference.
Stack (data structure) 2026-10-13
A stack is a data structure with last-in, first-out behavior: push adds an item at the top, pop removes and returns the top item, and peek inspects it without removal. Push : successive removals return . Inspection and removal require a nonempty stack, or a specified empty-case result. A linked list whose head is the top supports all three operations in worst-case time under constant-cost pointer operations and allocation. The stack interface itself does not fix these costs. [ref]
A stack records work that must be resumed in reverse order: the most recent unfinished task is handled first. Depth-first search uses this discipline to finish a newly entered branch before resuming the older branch that led to it. Breadth-first search uses a FIFO queue to resume the oldest pending vertex instead. Both are small interfaces whose removal rule changes the shape of a graph search.
A directed edge whose examination first discovers its target and recursively enters it. It becomes the target's parent edge in the depth-first search forest.
Two-pass strongly connected component algorithm Created 2026-10-25 Updated 2026-10-31
Run depth-first search on a finite directed graph, then search its graph transpose in decreasing first-pass finish order, marking vertices permanently during the second pass. Each second-pass search tree is one strongly connected component. The component finish-order property ensures that the next search cannot enter another still-unassigned component in the graph transpose; mutual reachability ensures that it reaches every vertex in its own component. Two traversals and transposition take time.