Prim’s Algorithm is an algorithm that computes the weight of the minimum spanning tree of a connected undirected graph with edge weights in

  • time and space, or
  • time and space.

Tip

This problem can also be solved by Kruskal’s Algorithm in time and space.

Tip

This problem can also be solved by Boruvka’s Algorithm in time and space.

Algorithm 0

Lemma

Let denote the set of minimum spanning trees of , denote the set of edges incident with . Then

  1. Fix a vertex in .

  2. Select an edge in .

  3. Solve for the graph obtained by contracting recursively.

Applying the lemma yields that the selected edges form a minimum spanning tree.

This algorithm solves the problem in time and space.

int prim(int n, int m, const std::vector<int> &u, const std::vector<int> &v, const std::vector<int> &w) {
	std::vector<std::vector<std::pair<int, int>>> adj(n);
	for (int i = 0; i < m; i++) {
		adj[u[i]].emplace_back(v[i], w[i]);
		adj[v[i]].emplace_back(u[i], w[i]);
	}
 
	std::vector dist(n, inf);
	dist[0] = 0;
	std::vector<int> s(n);
	std::iota(s.begin(), s.end(), 0);
	int sum = 0;
 
	while (!s.empty()) {
		int u = std::ranges::min(s, std::less(), [&](int u) -> int {
			return dist[u];
		});
		std::erase(s, u);
 
		sum += dist[u];
		for (auto [v, w] : adj[u]) {
			dist[v] = std::min(dist[v], w);
		}
	}
 
	return sum;
}

Algorithm 1

Based on Algorithm 0, using a Binary Heap to maintain the adjacency list of yields an algorithm that solves the problem in time and space.

int prim(int n, int m, const std::vector<int> &u, const std::vector<int> &v, const std::vector<int> &w) {
	std::vector<std::vector<std::pair<int, int>>> adj(n);
	for (int i = 0; i < m; i++) {
		adj[u[i]].emplace_back(v[i], w[i]);
		adj[v[i]].emplace_back(u[i], w[i]);
	}
 
	std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<>> q;
	q.emplace(0, 0);
	std::vector vis(n, false);
	int sum = 0;
 
	while (!q.empty()) {
		auto [d, u] = q.top();
		q.pop();
		if (vis[u]) {
			continue;
		}
		vis[u] = true;
 
		sum += d;
		for (auto [v, w] : adj[u]) {
			q.emplace(w, v);
		}
	}
 
	return sum;
}