Proofs: Thorup's linear-time undirected SSSP
These are the human proofs of Thorup's linear-time undirected SSSP, at full length.
Thorup's VISIT settles every vertex reachable from s at its distance full
This proof shows: correctness, termination.
Let be undirected with weights and source , and let . For a vertex and a level , write for the level- component that holds ; for a component on level and , write for the level- component that holds . Let ; every edge has weight below , so is the connected component of , and no edge joins to .
Fact 1 (crossing). If , every path from to a vertex of has an edge of weight at least .
Proof. If all its edges had weight below , all its vertices would be in one level- component, which would hold and meet , so it would be .
Invariants. At every time, (I1) every settled vertex has and the edges at have been relaxed in line L7; (I2) every is or the weight of a path from to , so . (I2) is clear: , and line L7 extends a path to by one edge. (I1) is shown below, in Lemma 4.
Lemma 2 (first unsettled vertex). Assume (I1). If is unsettled and , then on every shortest path from to the first unsettled vertex has .
Proof. If , , as weights are positive. Otherwise the vertex before on is settled, so by (I1) and the edge was relaxed, giving , since a prefix of a shortest path is shortest. With (I2), .
The precondition. For a component on level and a vertex , let be the largest with ; if , let . A call VISIT(, , hi) has the precondition at a given time if
- (P1) when : every unsettled has , and
- (P2) every unsettled has .
The root call VISIT(, , ) has it trivially: (P1) does not apply, and a vertex has no path from , so by (I2). For other calls, hi is a multiple of , by line L10.
Lemma 3 (the precondition holds for the whole call). If VISIT(, , hi) has the precondition when it starts, it has it at every time until it returns, provided (I1) holds.
Proof. While the call is active, every vertex settled is in , as every nested call is on a component inside . values only decrease, by line L7 at a settled vertex . By (P1), when , at the time is settled (it was unsettled just before). Consider a relaxation of .
If , the new value is , so (P1) stays true.
If , let . Since and , Fact 1 gives . The new value satisfies
since . So (P2) stays true. For the root, (P2) concerns only vertices outside , which no edge reaches.
Lemma 4 (children get the precondition). Suppose VISIT(, , hi) with has the precondition, and line L10 calls VISIT(, , ) with , and , where has the least among the unsettled vertices of and . Then the child call has the precondition.
Proof. (P1) for : every unsettled has .
(P2) for , case : then and , so . As above, , so .
(P2) for , case : for , so , and by (P2) for , . Finally : if this is clear, and otherwise hi is a multiple of , hence of , and gives .
Lemma 5 (settling is correct). Assume (I1) before line L6 runs in VISIT(, 0, hi), and that this call has the precondition. Then , so (I1) still holds after lines L6 and L7.
Proof. The call comes from line L10 with , so and ; in particular and . Suppose . Take a shortest path from to and its first unsettled vertex ; by Lemma 2, , so . The part of from to goes from into with , so by Fact 1 it has an edge of weight at least , and all its weights are positive. Hence, using (P2),
which contradicts . So . Line L7 then relaxes all edges at , so (I1) holds for .
By induction over the sequence of calls, Lemmas 3, 4 and 5 show that every call has the precondition when it starts and that (I1) holds throughout.
Lemma 6 (each child call makes progress). Every call VISIT(, , ) made in line L10 settles at least one vertex.
Proof. By induction on . When it is called, holds an unsettled with . If , line L6 settles . If , the condition of line L8 holds, so the loop runs at least once and makes a call that settles a vertex by induction.
Theorem. THORUP-SSSP terminates and returns for every .
Proof. Termination: a vertex is settled only while unsettled, so at most vertices are ever settled. By Lemma 6 every iteration of a loop in line L8 settles a vertex, so each call runs at most iterations, and the depth of the calls is at most . Hence the algorithm stops.
When the root call returns, the condition of line L8 fails for with , so every unsettled vertex of has . If some with were unsettled, Lemma 2 would give an unsettled on a shortest path to with , and ; a contradiction. So every vertex reachable from is settled, and by (I1) has . A vertex not reachable from keeps by (I2).