Prim's algorithm is a greedy algorithm used to find the Minimum Spanning Tree (MST) of a connected, undirected graph with weighted edges. The MST is a tree that spans all the vertices in the graph and has the minimum possible sum of edge weights.
Given a weighted graph, Prim’s algorithm builds the MST step by step, starting from an arbitrary node and adding the cheapest edge that connects a vertex in the tree to a vertex outside the tree.
Initialize:
Iterate:
u with the smallest key value from the priority queue.v of u, if v is not yet included in the MST and the weight of edge (u, v) is smaller than the current key value of v, update the key value of v.Repeat the above step until all vertices are included in the MST.
Terminate when all vertices are included in the MST, and the sum of the edges included will be the weight of the MST.
At each step, the algorithm picks the edge with the smallest weight that connects a vertex in the MST to a vertex outside the MST, ensuring that no cycles are formed.
V is the number of vertices.E is the number of edges.Let’s break down the working of Prim’s algorithm using a simple example:
Consider a graph with 5 vertices and the following edges with weights:
(0)---2---(1)
| |
6 3
| |
(2)---8---(3)
|
5
|
(4)
We will use Prim's algorithm to find the MST for this graph.
Start with Vertex 0:
key[0] = 0, and key[i] = ∞ for all other vertices.parent[i] = null for all vertices.Select Vertex 0:
key[1] = 2 (since it has a smaller weight than ∞).parent[1] = 0.Select Vertex 1:
key[3] = 3.parent[3] = 1.Select Vertex 3:
key[4] = 5.parent[4] = 3.Select Vertex 4:
key[2] = 5.parent[2] = 4.Finish:
The MST for the given graph includes the edges:
(0, 1, 2)
(1, 3, 3)
(3, 4, 5)
(4, 2, 5)
The total weight of the MST is 2 + 3 + 5 + 5 = 15.
Here’s a C++ implementation of Prim’s Algorithm using a priority queue to efficiently extract the minimum key value.
#include <iostream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
struct Edge {
int vertex, weight;
};
struct MinHeapNode {
int vertex, key;
bool operator>(const MinHeapNode& other) const {
return key > other.key;
}
};
void primsAlgorithm(int V, const vector<vector<Edge>>& adjList) {
// Initialize key values as infinity and parent array to store MST
vector<int> key(V, INT_MAX);
vector<int> parent(V, -1);
vector<bool> inMST(V, false); // Track vertices included in MST
// Priority queue to get the vertex with the minimum key value
priority_queue<MinHeapNode, vector<MinHeapNode>, greater<MinHeapNode>> pq;
// Start with the first vertex (vertex 0)
key[0] = 0;
pq.push({0, 0}); // {vertex, key}
while (!pq.empty()) {
// Get the vertex with the minimum key value
int u = pq.top().vertex;
pq.pop();
// Include the vertex in MST
inMST[u] = true;
// Explore all adjacent vertices of u
for (const Edge& edge : adjList[u]) {
int v = edge.vertex;
int weight = edge.weight;
// If v is not in MST and weight of (u, v) is smaller than key[v]
if (!inMST[v] && weight < key[v]) {
key[v] = weight;
parent[v] = u;
pq.push({v, key[v]});
}
}
}
// Print the MST
cout << "Edges in MST:" << endl;
for (int i = 1; i < V; ++i) {
cout << parent[i] << " - " << i << " : " << key[i] << endl;
}
}
int main() {
int V = 5; // Number of vertices
vector<vector<Edge>> adjList(V);
// Add edges: (u, v, weight)
adjList[0].push_back({1, 2});
adjList[0].push_back({2, 6});
adjList[1].push_back({0, 2});
adjList[1].push_back({3, 3});
adjList[2].push_back({0, 6});
adjList[2].push_back({3, 8});
adjList[2].push_back({4, 5});
adjList[3].push_back({1, 3});
adjList[3].push_back({2, 8});
adjList[3].push_back({4, 5});
adjList[4].push_back({2, 5});
adjList[4].push_back({3, 5});
// Call Prim's Algorithm to find the MST
primsAlgorithm(V, adjList);
return 0;
}
Data Structures:
Edge structure holds the vertex and the weight of an edge.MinHeapNode structure is used to store a vertex and its key value, which is used in the priority queue.Algorithm:
0 and initialize its key to 0.Output:
Open this section to load past papers