Dijkstra's Algorithm — Springs & Rings

The same shortest-paths algorithm, viewed as iterative edge relaxation on an undirected, weighted graph. The source s sits at the centre and every vertex floats at a radius equal to its current distance distTo[v] — the concentric rings are the distance scale, and the outermost dashed ring is (undiscovered, not to scale). Each edge u–v is a metal spring with natural length c(u,v); while distTo[v] > distTo[u] + c(u,v) the spring is stretched. Relaxing that edge lets the spring snap to its rest length, bouncing v inward to radius distTo[u] + c(u,v). The delete-min is the growing shaded disc around s: everything inside is settled/popped, the frontier ring is where the next minimum sits, and anything still stranded on the ∞ ring hasn't entered the queue yet.

850ms
Distance rings  ·  spring relaxation
undiscovered (∞ ring)
in priority queue
settled (inside disc)
current vertex
delMin frontier
edge = spring c(u,v)
Status
Press  Step  or  Play  to begin.
Priority Queue  ·  frontier
min ▸
empty
◂ rest
The frontier ring expands to the next min; vertices inside are settled, vertices on/outside are still queued (or on the ∞ ring, not yet discovered).
Distances  ·  distTo[v]
Edit / paste a graph
Format (Sedgewick & Wayne style): first line V, second line E, then E lines v w weight (weight ≥ 0). On this page edges are read undirected — direction is ignored and a repeated reverse pair w v is merged (keeping the lighter weight). The radial layout places each reachable vertex along the shortest-path tree, so tree edges look roughly radial and stretched non-tree springs cut across the rings.

Optional fixed layout: after the edges, add exactly V more lines of x y — one pair per vertex, in order. Since this page's radius is always distTo[v], only the angle (phase) of each coordinate relative to the source is used — pick positions in the rough direction you want each vertex to sit, any distance from the source works. Without coordinates the angle comes from the shortest-path tree instead, with a random rotation each load. Loading a graph always fills the box back in with coordinates so you can nudge them; tick the box above to see the plain format instead.

Mixed-format tolerant: each edge occupies exactly one line. Pasting an unweighted graph here (only two numbers per edge line) just defaults each missing weight to 1, instead of failing to parse.