Same MST, different strategy from Kruskal. Prim grows a single tree from a start node, repeatedly absorbing the cheapest edge that reaches a node not yet in the tree.
Start with any node. Look at all edges crossing from the tree to the outside (the cut). Pick the lightest one, add its far node to the tree, repeat until everyone's in.
int prim(int n, vector<vector<pair<int,int>>>& adj) {
vector<bool> inMST(n, false);
priority_queue<pair<int,int>, vector<pair<int,int>>,
greater<>> pq; // {weight, node}
pq.push({0, 0}); // start from node 0, cost 0
int cost = 0, used = 0;
while (!pq.empty() && used < n) {
auto [w, u] = pq.top(); pq.pop();
if (inMST[u]) continue; // already absorbed, discard
inMST[u] = true;
cost += w; used++;
for (auto& [v, wt] : adj[u])
if (!inMST[v]) pq.push({wt, v}); // push frontier edges
}
return used == n ? cost : -1; // -1 if disconnected
}
Binary-heap version. Each edge can trigger one heap push.
Adjacency list, in-MST flags, and the heap.
An array-based Prim beats the heap when E ≈ V².
if (inMST[u]) continue guard is lazy deletion, same trick as Dijkstra's stale-entry skip.inMST flag alone prevents cycles.w instead of cumulative distance.