Depth-first search computes minimax search values with much less live storage and naturally supports alpha-beta pruning. A parent's value needs only its current best child value and the next child to visit. Once a child subtree has been evaluated, its internal search nodes can be discarded; a final value cannot usually be computed from a nonterminal frontier alone.
With branching factor and horizon , breadth-first search stores a frontier of order . A depth-first search implementation storing sibling lists uses space complexity; lazy successor generation can reduce this to frames plus game-state storage. Both unpruned traversals have time complexity for . Depth-first search also supplies a completed sibling outcome early, allowing alpha-beta pruning to reject later subtrees before generating them.
For a finite constraint satisfaction problem with variables, all complete assignments have depth when each step assigns one new variable. Thus the shallowest-solution property of breadth-first search offers no advantage: every complete solution is already at that depth.
Depth-first search with backtracking stores a path and pending choices, using auxiliary space with ordinary explicit choice bookkeeping, or when each level stores only a current value index. Breadth-first search may store an exponentially large frontier, up to partial assignments. Depth-first search can also combine naturally with immediate constraint propagation and undoing changes. The finite depth avoids the infinite-branch obstruction of unrestricted depth-first tree search. Neither traversal removes the possible exponential time complexity.
Given a feasible network flow , an original directed edge has forward residual capacity and a reverse residual arc of capacity . A source–sink graph path in this residual network permits an augmentation by the minimum residual capacity along it: increase forward flows and decrease the corresponding reversed flows. Capacities and flow conservation are preserved, and the flow value increases by that amount.
If no residual source–sink graph path exists, let be the vertices reachable from the source. The sink is outside . Every original arc from to its complement is saturated, and every original arc back into has zero flow, since a positive reverse residual arc would make its tail reachable. Conservation therefore gives
The flow equals this cut capacity, so the max-flow min-cut theorem proves it is maximum.
Termination needs a capacity or path-selection assumption. For integer capacities, starting from zero, every residual capacity and augmentation is integral; each augmentation increases the value by at least one, and the value is bounded by the total source-outgoing capacity. The algorithm therefore terminates. Rational capacities can be scaled to integers. With arbitrary real capacities, unrestricted graph path choices do not guarantee finite termination. A valid uniformly terminating implementation is the Edmonds–Karp algorithm, choosing a shortest residual graph path each time.
Here is why that choice works independently of numerical capacity sizes. Residual distances from the source cannot decrease after augmenting along a shortest graph path. Every newly created residual arc is the reverse of a graph path arc; if it could cause the first distance decrease, its previous distance relation would contradict that decrease. When an arc is saturated on a shortest graph path, . Before the same direction can be saturated again, it must have been restored by a reverse augmentation on a shortest graph path, at which time . Each arc is consequently critical only times. There are arcs and each augmentation saturates at least one, giving augmentations, each found by breadth-first search in time. Thus the shortest-path Ford–Fulkerson implementation terminates and finds a maximum flow in arithmetic operations.
For sports elimination by maximum flow, first give the target team all its remaining wins. This cannot hurt its chance to finish strictly ahead: changing a result to favour it also removes a rival's win. Let be its resulting win count. If any rival already has at least wins, strict victory is impossible. Otherwise give each unordered pair of rivals one game node. Its incoming capacity is , and its two outgoing arcs go to the participating team nodes. Their capacities may be replaced by the finite number
since no arc can need more than the total number of remaining rival games. Team has sink capacity .
An integral flow of value saturates all game-node incoming arcs. Its two outgoing amounts allocate exactly wins to the two teams; the team-sink caps keep each rival strictly below . Conversely any successful completion of the league specifies such a flow. Integral capacities and augmentation give an integral maximum flow, so
after the initial negative-capacity rejection. Each actual game is counted once: making independent nodes for both ordered pairs would double-count it.
The network has nodes and arcs. If each input integer has at most bits, its derived capacities have bits. The shortest-path algorithm above uses arithmetic operations, each on integers of polynomial bit length. Therefore the decision problem belongs to P, even with part of the input. If is fixed, even the basic integral-augmentation bound is polynomial in . If varies, that particular bound is only pseudopolynomial; it is the shortest-path implementation that establishes polynomial bit complexity.
Run breadth-first search separately in every component of the undirected graph. Give a starting vertex colour zero and each newly discovered neighbour the opposite colour. Reject if an edge joins two vertices with the same assigned colour; otherwise accept after all components have been explored.
If the algorithm accepts, its assignments constitute a graph colouring with two colours. If it rejects, the two search-tree paths and the conflicting edge contain an odd cycle, on which alternating two colours cannot close consistently. Equivalently, a valid graph colouring with two colours fixes the parity of every path from a component's root, so the detected conflict is impossible in a two-colourable graph. The breadth-first search work is with adjacency lists. Therefore
This is also the two-colourability criterion for bipartite graphs.
The regular language is nonempty because it represents every element of the group. Find any accepted word using breadth-first search in its finite-state automaton. If is the empty word, it already represents the identity.
Otherwise begin with and repeatedly apply the linear-time multiplication in an automatic structure to the letters
These letters belong to by symmetry of the alphabet. All intermediate words lie in , and the final word represents
Hence an identity representative can be constructed effectively:
This is a finite preliminary computation depending only on the fixed automatic structure for a group; it uses no test for whether an arbitrary word represents the identity.
If a cubic graph has no cycle of length at most , the breadth-first search ball of radius about a vertex is a tree and contains
vertices. Taking gives a contradiction for a suitable nearby radius, and in particular yields a cycle of length at most .
Choose such a cycle of length . Removing its vertices deletes at most edges. The remaining graph has at least edges on vertices. For all sufficiently large , this exceeds , so part (a) says the remainder contains a cycle. It is vertex-disjoint from .
Explore the connected component of a graph containing a fixed vertex by breadth-first search. If the exploration discovers at least vertices, then before its th discovery at least of at most tested potential edges must be present. The tests are independent Bernoulli trials with parameter , so
The binomial distribution on the right has mean . For , the exponential Markov bound gives
for an absolute constant . The union bound over the choices of now gives
Taking with makes this probability tend to zero. This proves the subcritical component bound for a binomial random graph.
Replace breadth-first search by Dijkstra's algorithm from , using the positive edge weights to compute . The strongly connected components, the condensation graph and the reverse-topological order propagation are unchanged, because reachability ignores weights. Only the label assigned to a reachable vertex changes.
With a binary heap, the total time is , including the linear component-processing stages. More specialized priority queues give their corresponding shortest-path bounds. The proof still compares the precomputed distances from ; it must not add the weight of a path from to the candidate, which would optimize a different quantity.
First run breadth-first search from to compute each distance . All are finite by hypothesis. Next compute the strongly connected components and their condensation graph . For every component , initialize a representative minimizing over . Process components in reverse topological order, using
Break equal-distance ties consistently, for example by fixed vertex index. Return for every .
Every vertex of one strongly connected component reaches every other; every reachable different component is reached through some first outgoing edge of . Since is a Directed acyclic graph, reverse topological order has already solved every successor. Induction over that order proves that the representative minimizes over all reachable vertices. This is minimum reachable label propagation.
All stages take time and space with explicit adjacency lists. Retaining parallel component edges is harmless: they can be scanned once each without sorting or deduplication. Reachability here includes the length-zero path, so ; this standard convention also makes the requested answer meaningful at a sink.
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.
Give each solving session a shared visited set keyed by immutable snapshots of permutation contents, for example game.toList, and insert the initial snapshot immediately. Have all successor objects refer to that same session's set. The refined flip first constructs the candidate state; if its key is present, return None. Otherwise add the key immediately and return Some(candidate). The search enqueues only Some results. Keys must compare contents rather than array identities, and a fresh solving session must start with a fresh visited set.
Marking at generation time prevents the same state from being queued repeatedly, including the immediate cycle made by applying the same reversal twice. First discovery in breadth-first search already has minimum depth, so discarding later discoveries cannot remove a shorter solution. The graph now has at most admitted states. If only cycles along one path were to be rejected, a path-local set would suffice, but it would still repeat states reached by different paths; the shared session-wide set avoids both kinds of repetition. Public game fields must not be externally mutated while their states are being searched.
Use the heap-numbered binary tree with root label zero and children . Its strict descendants in breadth-first search order are . A machine-safe Node[Int] version stops at the largest representable label:
class NumberNode(val label: Int) extends Node[Int] {
  require(label >= 0)
  def children(): Iter[Node[Int]] = new Iter[Node[Int]] {
    private var candidate = 2L * label.toLong + 1L
    private val last = candidate + 1L
    def hasNext: Boolean = candidate <= last && candidate <= Int.MaxValue
    def next(): Node[Int] = {
      require(hasNext)
      val answer = new NumberNode(candidate.toInt)
      candidate += 1L
      answer
    }
  }
}

val traversal = breadthFirst(new NumberNode(0))
var expected = 1
while (expected <= 1000) {
  assert(traversal.hasNext)
  assert(traversal.next().label == expected)
  expected += 1
}
The arithmetic is widened before computing child labels, so no negative wrapped labels occur. Repeated hasNext calls should not skip nodes; a leaf root should produce immediate exhaustion, and uneven finite trees should retain sibling order across parents. A fresh second traversal should start again at one.
Literal unbounded increase is impossible with the bounded Int type. For a genuinely infinite test, change the label and child arithmetic to BigInt; the same construction then has no representational endpoint. The shown finite-prefix test already exercises lazy traversal without allocating the entire very large Int-labelled tree.
First run breadth-first search, ignoring weights, to obtain the minimum number of edges from the source to each reachable vertex. Then compute weighted distances only along edges that advance one breadth-first layer:
d[source] = 0; all other d[v] = infinity
for u in nondecreasing BFS-layer order:
    for each outgoing edge (u,v):
        if h[v] == h[u]+1:
            if d[u]+w(u,v) < d[v]:
                d[v] = d[u]+w(u,v)
                predecessor[v] = u
Unreachable vertices keep distance . For an undirected graph, scan both orientations of each edge.
To justify discarding other routes, a shortest path can be taken simple because every weight is positive. A simple path of edges has weight in
Every path with at least edges weighs at least . Consequently every minimum-weight path must also have the minimum possible number of edges: this is minimum-hop dominance for nearly unit weights.
A minimum-hop path to uses exactly edges. Every prefix of such a path must itself have minimum hop count, since replacing a longer prefix by a shorter one would shorten the whole route. Hence it advances from layer to layer at every step. The retained edges form a Directed acyclic graph, ordered by . The displayed dynamic programming recurrence therefore finds the cheapest of all minimum-hop paths, which by the preceding bound is a true shortest path.
Figure 1.
Disjoint weight bands for simple paths with different hop counts
. Details.
With an adjacency list, both the breadth-first search and the layer-ordered relaxations take time and total storage, where . The queue order from breadth-first search already supplies the layer order; no sorting or priority queue is needed. This improves the usual binary-heap Dijkstra bound and is linear in the input size.
Prefix reversal Created 2026-10-24 Updated 2026-10-31
Reverse the first entries of a sequence and leave its suffix unchanged. On a permutation, this is a bijection on positions and is its own inverse: performing the same reversal twice restores the state. The nontrivial moves have . With unit-cost moves, the resulting state graph supports a breadth-first search for a minimum-move solution.
Prefix reversal sorting Created 2026-10-24 Updated 2026-10-31
To sort a permutation using prefix reversals, work backwards through final positions. On an active prefix of length , find its largest value. If it is already at the final position, shorten the active prefix. Otherwise move it to the front with one reversal if necessary, then reverse the entire active prefix to put it last. Already settled suffix positions are untouched.
The settled suffix is a loop invariant, and active-prefix length decreases to one. This proves reachability of the identity permutation in at most nontrivial flips. The construction is a finite upper bound, not a promise of minimum length; breadth-first search can find the minimum for small instances.
Rooted tree Created 2026-09-28 Updated 2026-10-14
A rooted tree is a tree with a distinguished vertex, its root of a tree . Choosing turns connections into a hierarchy: every other vertex has a unique parent in a rooted tree, the preceding vertex on its graph path from . Conversely, the vertices whose parent in a rooted tree is are the children in a rooted tree of . Choosing the root of a tree changes this description, while the underlying edges remain the same. Arrows towards the root of a tree can encode the relationship, as in MIT's counting notes; the undirected tree itself needs no arrows. [ref]
In the seven-vertex tree above, choose . The levels, grouped by graph distance from the root of a tree, are , , , . The children in a rooted tree of are , and the parent in a rooted tree of is . Choosing instead makes the levels , , , , , : now has parent in a rooted tree , reversing their relationship. All six edges survive.
This hierarchy supports structural recursion: process the smaller rooted trees below each vertex, then combine their results. A depth-first traversal of a tree explores one branch before returning; breadth-first search processes successive levels. The lowest common ancestor identifies where two routes from the root of a tree last coincide. For it is when . A binary tree imposes an additional restriction on children in a rooted tree; a general rooted tree has no such bound.
Shortest path problem 2026-10-14
The shortest path problem asks for a graph path from a source vertex to a destination vertex minimizing its total edge weight. Here is the cost of traversing edge , and costs add along the graph path. If no route exists, its shortest-path distance is . With nonnegative edge weights, deleting cycles in a graph from a walk never increases its cost, so repetitions cannot improve the optimum.
Consider the undirected graph with vertex set and the six edge weights
Each edge can be traversed in either direction at the same cost. The direct graph path costs ; costs ; costs . The cheapest graph path is , costing . The remaining graph path costs , exhausting the possibilities without repeated vertices.
Figure 1.
The shortest path problem: three highlighted edges cost less than the direct connection
. Details.
Thus fewest edges and least total cost are different objectives. Breadth-first search minimizes the number of edges, which suffices when every edge has the same positive cost. Unequal nonnegative costs call for the Dijkstra algorithm. On a map, weights might be minutes rather than kilometres: a longer-looking route can arrive sooner. This is why a weighted graph separates the network's connections from what a particular journey costs.
Spanning tree Created 2026-09-24 Updated 2026-10-14
A spanning tree of a connected graph is a subgraph that is a tree and contains every vertex of . Its edges must come from . For finite on vertices, every spanning tree has edges, the minimum possible number preserving reachability between all locations. This makes a spanning tree a compact certificate that the original graph is connected. A minimum spanning tree additionally minimizes a specified total edge weight; merely selecting a spanning tree supplies no such optimization. [ref]
Let be our seven-vertex tree with edge added. It has seven edges and a graph cycle. Removing gives the original spanning tree ; removing instead gives another spanning tree . Both retain all seven vertices and six edges, but their graph distances differ: , whereas . In , but , along , compared with . Preserving reachability permits longer journeys; breadth-first search can preserve graph distances from one chosen starting vertex.
To construct a spanning tree, repeatedly delete any edge on a graph cycle. Its endpoints remain joined through the rest of that graph cycle, so the deletion preserves connectedness. Finiteness ensures that this stops at a connected acyclic graph. Conversely, adding an omitted edge to a spanning tree creates its unique fundamental cycle; deleting any other edge on that graph cycle produces another spanning tree. The displayed exchange replaces by . [ref]
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.
For , choose independent random variables, each with the uniform distribution on a finite set , and decode their values as a Prüfer sequence. Every sequence has probability , and the bijection gives each labelled tree the same probability. This produces a uniform spanning tree of the complete graph without repeatedly proposing sets of edges and rejecting those that fail to be trees. It supplies random inputs for testing implementations of breadth-first search and a tractable model of random connections. [ref]
This distribution is uniform over fixed-label trees, rather than over unlabelled trees. With four labels, the star graph shape has probability and the path graph shape has probability . Also, for a fixed label , the Prüfer degree formula gives
Here the binomial distribution counts the independent code positions equal to . The expected value agrees with the average vertex degree from the degree-sum formula. Individual labels have the same distribution by symmetry, though their vertex degrees are constrained together by their fixed sum. When , simply return the single isolated vertex.