// adj: Array of arrays of {to, w}; start from node 0 (or any)
function prim(adj, s = 0) {
const n = adj.length; const used = Array(n).fill(false);
const heap = [];
const up = (i)=>{ while(i){ const p=(i-1)>>1; if(heap[p][0]<=heap[i][0]) break; [heap[p],heap[i]]=[heap[i],heap[p]]; i=p; } };
const down=(i)=>{ for(;;){ let l=i*2+1,r=l+1,m=i; if(l{ heap.push(x); up(heap.length-1); };
const pop=()=>{ const t=heap[0]; const last=heap.pop(); if(heap.length){ heap[0]=last; down(0);} return t; };
used[s]=true; let total=0; const mstEdges=[];
for (const e of adj[s]) push([e.w, s, e.to]);
let picked=0;
while (heap.length && picked < n-1) {
const [w, u, v] = pop(); if (used[v]) continue;
used[v]=true; total+=w; mstEdges.push({u, v, w}); picked++;
for (const e of adj[v]) if (!used[e.to]) push([e.w, v, e.to]);
}
// If graph disconnected, picked < n-1 -> spanning forest for reachable nodes
return { edges: mstEdges, weight: total };
}
- Complexity: O(m log n) with a binary heap and adjacency list.
- When good: dense-ish graphs or when starting from a vertex is convenient.