Minimum spanning tree (Prim's)

Grow one tree outward from a start node, always adding the cheapest edge that reaches a new node.

Time O(E log V)Space O(V)Code C#
Watch it animatedStep through it, with the running line highlighted. Free with an account.

The idea

Keep a frontier of candidate edges leaving the tree built so far. Always take the cheapest one. If it reaches a node already in the tree, it would only create a cycle, so skip it; otherwise the new node joins the tree and its edges become new candidates.

Code

public static List<(char, char, int)> Prim(
        Dictionary<char, List<(char to, int w)>> graph, char start) {
    var inTree = new HashSet<char> { start };
    var pq = new PriorityQueue<(char u, char v, int w), int>();
    foreach (var (v, w) in graph[start]) pq.Enqueue((start, v, w), w);
    var tree = new List<(char, char, int)>();
    while (pq.Count > 0) {
        var (u, v, w) = pq.Dequeue();
        if (inTree.Contains(v)) continue; // both ends already joined, skip
        inTree.Add(v);
        tree.Add((u, v, w));
        foreach (var (x, wx) in graph[v])
            if (!inTree.Contains(x)) pq.Enqueue((v, x, wx), wx);
    }
    return tree;
}

Tips

In the .NET library

Prim grows one connected tree outward, while Kruskal picks edges globally by weight regardless of which tree they touch. On the same graph with distinct weights they produce the same tree, just discovered in a different order.