# Prim's Algorithm in C++

Prim's algorithm is a greedy algorithm used for finding the minimum spanning tree (MST) of a connected, undirected graph. The minimum spanning tree of a graph is a subset of the edges that forms a tree and connects all the vertices in the graph while minimizing the total edge weight. Prim's algorithm ensures that the MST is created by adding edges with the minimum weight.

## History

Prim's algorithm, named after Czech mathematician and computer scientist Robert C. Prim, is a fundamental algorithm in graph theory and computer science used for finding the minimum spanning tree (MST) of a connected, undirected graph. Here's a brief history of Prim's algorithm:

### Origin of Minimum Spanning Trees:

The concept of minimum spanning trees dates back to the early 20th century, with applications in electrical network design and transportation.

### Borůvka's Algorithm (1926):

The earliest precursor to Prim's algorithm was developed by Czech mathematician Otakar Borůvka in 1926. Borůvka's algorithm aimed to find an approximate solution to the minimum spanning tree problem.

### Prim's Algorithm (1957):

In 1957, Robert C. Prim, an American mathematician, independently rediscovered and published the algorithm that would later bear his name. His work was motivated by the construction of efficient electrical networks.

### Edsger W. Dijkstra (1959):

Dutch computer scientist Edsger W. Dijkstra independently rediscovered and popularized Prim's algorithm in the context of computer science. His presentation of the algorithm in 1959 helped establish its significance in computer science and graph theory.

### Proof of Correctness:

The algorithm's correctness was rigorously proved by computer scientists R.C. Prim and Vojt?ch Jarník in the late 1950s and early 1960s.

Prim's algorithm gained wide adoption in computer science and graph theory due to its simplicity and efficiency. It became a fundamental algorithm for solving problems involving minimum spanning trees.

### Application in Network Design:

Prim's algorithm found applications in various fields, including network design, circuit layout, and transportation planning.

### Computer Science Textbooks:

The algorithm's inclusion in computer science textbooks and courses further contributed to its prominence and understanding.

### Later Developments:

Over the years, variations and improvements to Prim's algorithm have been proposed, such as Prim-Jarník algorithm and various data structures to optimize its performance.

Prim's algorithm remains a fundamental tool in graph theory and computer science for solving problems related to network design and optimization. It is known for its simplicity, efficiency, and ability to consistently find minimum spanning trees in connected, undirected graphs.

### Here's a deep explanation of how Prim's algorithm works:

Input:

• A connected, undirected graph.
• A starting vertex to begin the MST construction.

Output:

• The minimum spanning tree.

### Algorithm Steps:

Initialization:

• Create an empty set MST to store the edges of the MST.
• Create an array key[] to keep track of the minimum edge weight for each vertex. Initialize it with infinity for all vertices except the starting vertex, which is set to 0.
• Create an array parent[] to store the parent of each vertex in the MST. Initialize it with -1 for all vertices.

Iterative Process:

• While there are vertices not yet included in MST, do the following steps:
• Choose a vertex u not in MST with the minimum key[u] value. Initially, this will be the starting vertex.
• Add u to MST.
• For each neighbor v of u that is not in MST, if the weight of the edge (u, v) is less than key[v], update key[v] to the weight of (u, v) and set parent[v] to u.

Termination:

Once all vertices are included in MST, you have constructed the minimum spanning tree.

Result:

The set of edges in MST forms the minimum spanning tree of the given graph.

## Implementation:

### Approach 1:

OUTPUT:

```Enter the number of vertices: 5
Enter the adjacency matrix of the graph:
0 2 0 1 0
2 0 3 2 5
0 3 0 0 4
1 2 0 0 6
0 5 4 6 0
Edges of Minimum Spanning Tree:
Edge: 0 - 3 Weight: 1
Edge: 1 - 3 Weight: 2
Edge: 3 - 4 Weight: 6
Edge: 1 - 2 Weight: 3
```

Explanation:

Initialization:

• The algorithm starts by selecting an arbitrary vertex as the initial vertex. This vertex is added to the MST, and its key (the minimum edge weight to connect to it) is set to 0. All other vertices are initially marked with infinite key values.
• A data structure (often a priority queue) is used to keep track of candidate edges to add to the MST, prioritized by their key values.

Iterative Process:

While there are vertices that haven't been added to the MST, the algorithm continues:

• It selects the vertex with the smallest key value among the vertices not in the MST. This vertex becomes the next vertex to be added to the MST.
• The algorithm explores all edges connected to the selected vertex and checks if any of these edges lead to a vertex with a smaller key value. If such an edge is found, the key value and the parent of the adjacent vertex are updated, and the edge is added to the MST candidate list.
• The above steps are repeated until all vertices are included in the MST.

Termination:

Once all vertices are included in the MST, the algorithm terminates.

Result:

The MST is formed by the edges that were selected during the algorithm's execution.

The key idea behind Prim's algorithm is to grow the MST one vertex at a time, always selecting the vertex with the smallest key value and adding the edge with the smallest weight that connects to it. This ensures that the MST is built by adding edges with minimal weights, guaranteeing an optimal solution.

The algorithm maintains three main data structures:

• A set to keep track of vertices included in the MST.
• An array (or other data structure) to store key values for each vertex.
• A data structure (e.g., a priority queue) to efficiently select the next vertex to add to the MST based on its key value.

By iteratively selecting vertices and updating key values, Prim's algorithm constructs the minimum spanning tree of the given graph efficiently and optimally.

### Approach 2:

OUTPUT:

```Enter the number of vertices: 5
Enter the number of edges: 7
Enter the edges and their weights (from to weight):
0 1 2
0 3 1
1 2 3
1 3 2
1 4 5
2 4 4
3 4 6
Edges of Minimum Spanning Tree:
Edge: 0 - 3 Weight: 1
Edge: 3 - 1 Weight: 2
Edge: 1 - 2 Weight: 3
Edge: 1 - 4 Weight: 5
```

Explanation:

Custom Classes for Graph and Edge:

• We define two custom classes, Edge and Graph, to represent the graph and its edges.
• Edge stores the target vertex (to) and the weight of the edge.
• Graph contains the number of vertices (V) and an adjacency list (adj) to represent the graph's edges.

Function to Add Edges to the Graph (addEdge):

• In the Graph class, we have a member function addEdge that allows us to add edges to the graph.
• It takes the source vertex (from), target vertex (to), and edge weight as arguments and adds the edge to the adjacency list. Additionally, it adds the reverse edge for undirected graphs.

Prim's Algorithm (primMST Function):

• This function finds the Minimum Spanning Tree (MST) of the graph using Prim's algorithm.
• It takes the Graph object as an argument.

Initialization:

• We initialize arrays to keep track of key values (minimum edge weights), parent vertices, and a boolean array inMST to track whether a vertex is included in the MST.
• The priority_queue (pq) is used as a min-heap to select edges with minimum weights.

Main Algorithm Loop:

• We start by adding the first vertex (vertex 0) as the initial vertex with a key value of 0.
• The algorithm iterates until all vertices are included in the MST.
• In each iteration, it selects the vertex u with the smallest key value from the min-heap (pq).

Vertex Inclusion:

The selected vertex u is marked as included in the MST by setting inMST[u] to true.

• The algorithm explores all adjacent vertices of u and checks if there's an edge with a weight smaller than the current key value for that vertex.
• If such an edge is found, it updates the key value and the parent vertex for that adjacent vertex.
• The adjacent vertex is then added to the min-heap for further consideration.

Termination:

The algorithm continues until all vertices are included in the MST.

Printing the MST:

After the algorithm completes, we print the MST edges by iterating through the parent array and displaying the selected edges along with their weights.

Main Function:

In the main function, we take user input for the number of vertices and edges, create a Graph object, add edges to it using the addEdge function, and finally call primMST to find and print the MST.

## Examples:

### Example 1: Adjacency Matrix

OUTPUT:

```Enter the number of vertices: 5
Enter the adjacency matrix:
0 2 0 1 0
2 0 3 2 5
0 3 0 0 4
1 2 0 0 6
0 5 4 6 0
Edge   Weight
0 - 3   1
3 - 1   2
1 - 2   3
0 - 4   5
```

Explanation:

• Initialization:

Choose a starting vertex as the initial node of the Minimum Spanning Tree (MST).

Create data structures to keep track of the MST:

key[]: An array to store the minimum edge weight to connect each vertex to the MST. Initialize all values to infinity except for the starting vertex, which is set to 0.

mstSet[]: An array or set to keep track of which vertices are included in the MST. Initialize all values to false.

• Iterative Process:

Repeat the following steps until all vertices are included in the MST:

Select a vertex u that is not in the MST and has the minimum key value.

Add u to the MST.

Update the key values of adjacent vertices of u if they are not already in the MST and if the edge weight to u is smaller than their current key value.

• Termination:

When all vertices are included in the MST, the algorithm terminates.

• Result:

The Minimum Spanning Tree (MST) is formed by the edges that were selected during the algorithm's execution. These edges connect all vertices while minimizing the total edge weight.

### Example 2: Adjacency List

OUTPUT:

```Enter the number of vertices: 5
Enter the number of edges: 7
Enter the edges (from to weight):
0 1 2
0 3 1
1 2 3
1 3 2
1 4 5
2 4 4
3 4 6
Edges of Minimum Spanning Tree:
Edge: 0 - 3 Weight: 1
Edge: 1 - 3 Weight: 2
Edge: 3 - 4 Weight: 6
Edge: 1 - 2 Weight: 3
```

Explanation:

Step 1: Initialization

• Choose a starting vertex arbitrarily from the graph.
• Create data structures to keep track of the Minimum Spanning Tree (MST) construction:
• key[]: An array to store the minimum edge weight required to connect each vertex to the MST. Initialize all values to infinity except for the starting vertex, which is set to 0.
• parent[]: An array to store the parent of each vertex in the MST. Initialize all values to -1.
• inMST[]: A boolean array or set to keep track of which vertices are already included in the MST. Initialize all values to false.

Step 2: Grow the MST

Repeat the following steps until all vertices are included in the MST:

• Find the vertex u that is not in the MST and has the minimum key value.
• Add vertex u to the MST.
• Update the key values of all adjacent vertices of u if they are not already in the MST and if the edge weight to that vertex is smaller than their current key value.
• Update the parent of adjacent vertices to u for the edges added in step c.
• Mark vertex u as included in the MST by setting inMST[u] to true.

Step 3: Termination

When all vertices are included in the MST, the algorithm terminates.

Step 4: Result

The Minimum Spanning Tree (MST) is formed by the edges that were selected during the algorithm's execution. These edges connect all vertices while minimizing the total edge weight.

### Applications:

• Network Design:

Prim's algorithm is commonly used in network design problems, such as the design of computer networks, electrical power distribution networks, and telecommunications networks. It helps minimize costs while ensuring connectivity.

• Circuit Design:

In electronic circuit design, Prim's algorithm can be employed to optimize the layout of components on a circuit board, minimizing wire lengths and connections.

• Transportation and Urban Planning:

Prim's algorithm can be applied to urban planning for optimizing transportation routes, such as road networks, subway systems, or bus routes, to reduce travel distances and congestion.

• Maze Generation:

It is used to generate mazes, where the goal is to create a connected maze with a minimal number of walls or passages.

• Image Segmentation:

In image processing and computer vision, Prim's algorithm can be used for segmenting images into regions or components with minimal boundary cost.

• Cluster Analysis:

Prim's algorithm can be applied in clustering and hierarchical clustering techniques to group data points based on their similarity, forming a minimum spanning tree of data points.

• Spanning Tree Algorithms:

Prim's algorithm serves as a foundational component in other algorithms and data structures, such as Boruvka's algorithm and Kruskal's algorithm, which also find minimum spanning trees.

• Routing Protocols:

In computer networking, Prim's algorithm can be used to build routing tables or determine the best paths in network routing protocols like OSPF (Open Shortest Path First).

• Energy Distribution:

It can optimize the distribution of resources, such as electricity, water, or gas, in a network, minimizing the length of connections and infrastructure costs.

• Wireless Sensor Networks:

Prim's algorithm can help create efficient communication topologies in wireless sensor networks, where energy efficiency and connectivity are critical.

• Data Clustering and Visualization:

Prim's algorithm can be applied in data clustering and visualization tasks to identify clusters or connected components within datasets.

• Game Development:

In game development, Prim's algorithm can be used to generate game maps and layouts, ensuring that game environments are connected and navigable.

• Spanning Tree in Graph Algorithms:

Minimum spanning trees are used as subproblems in other graph algorithms, making Prim's algorithm a foundational concept in computer science.

Prim's algorithm offers several advantages that make it a valuable choice for finding minimum spanning trees (MSTs) in various applications.

• Optimality: Prim's algorithm guarantees that the MST it produces is optimal, meaning it has the smallest possible total edge weight among all possible spanning trees in the graph. This optimality property is essential in many real-world scenarios where minimizing costs is crucial.
• Efficiency: Prim's algorithm is highly efficient, especially for dense graphs. Its time complexity is typically O(V^2), where V is the number of vertices, which makes it practical for solving large-scale problems. With the use of more advanced data structures like binary heaps or Fibonacci heaps, it can achieve a time complexity of O(E + V log V), where E is the number of edges.
• Ease of Implementation: The algorithm is relatively easy to implement and understand. It involves simple data structures like arrays, priority queues, or heaps, making it accessible for programmers and engineers.
• Versatility: Prim's algorithm can be applied to various types of graphs, including weighted, connected, and undirected graphs. It can handle both dense and sparse graphs, making it a versatile choice for MST problems.
• Distributed Computation: Prim's algorithm is amenable to distributed and parallel computation. In scenarios where the graph is distributed across multiple processors or nodes, the algorithm can be adapted to work efficiently in such environments.
• Incremental Construction: Prim's algorithm constructs the MST incrementally, allowing for easy monitoring and visualization of the growing MST. This can be useful in various applications where the step-by-step construction of the MST is informative.
• Reduced Complexity in Sparse Graphs: In sparse graphs (where the number of edges is much less than the number of vertices squared), Prim's algorithm can be faster than Kruskal's algorithm, another popular MST algorithm.
• Applications Beyond MST: Prim's algorithm serves as a building block for other graph algorithms and data structures. Variants of the algorithm are used in various applications, such as shortest path algorithms and network routing.
• Guaranteed Connectivity: The MST produced by Prim's algorithm is guaranteed to be a connected tree that spans all vertices in the graph. This property is crucial in applications where connectivity is essential.
• Simplicity and Intuitiveness: The algorithm's greedy approach, which selects edges with the smallest weights, is easy to grasp intuitively. This makes it a good choice for educational purposes and for solving problems where a simple and clear solution is preferred.

Prim's algorithm's combination of optimality, efficiency, and ease of implementation makes it a valuable tool for solving a wide range of problems in various domains, from network design to image processing to game development.

### How Prim's Algorithm is different from other algorithms

Prim's algorithm, while a powerful and widely used algorithm for finding minimum spanning trees, has competitors or alternatives that can also solve the same problem. Here are some of the main competitors or alternatives to Prim's algorithm for finding minimum spanning trees:

• Kruskal's Algorithm:

Kruskal's algorithm is another popular algorithm for finding minimum spanning trees. It operates by sorting all the edges by weight and then adding them to the MST in ascending order of weight, as long as they do not create cycles. Kruskal's algorithm has a time complexity of O(E log E), where E is the number of edges, and is often preferred when the graph is sparse.

• Borůvka's Algorithm:

Borůvka's algorithm is an early precursor to Prim's algorithm and Kruskal's algorithm. It was designed to find an approximate solution to the minimum spanning tree problem by repeatedly contracting the graph into smaller components.

• Reverse-Delete Algorithm:

The Reverse-Delete algorithm starts with all edges in the graph and iteratively removes the edges with the highest weights while maintaining connectivity. This process continues until the graph becomes a spanning tree. It can be less efficient than Prim's or Kruskal's algorithm for dense graphs.

• Boruvka-Minimum Spanning Tree Algorithm:

This algorithm is a modification of Borůvka's algorithm designed to find an approximate MST efficiently. It divides the graph into smaller connected components and computes the MST for each component, then connects these MSTs to form the final MST.

• Jarník's Algorithm (also known as Prim-Jarník or Prim's Algorithm with Fibonacci Heaps):

An optimized version of Prim's algorithm that uses Fibonacci heaps to speed up the priority queue operations, resulting in a faster implementation with a time complexity of O(E + V log V). This variant is especially efficient for dense graphs.

• Randomized Algorithms:

Randomized algorithms, such as Randomized Prim's Algorithm and Randomized Kruskal's Algorithm, introduce randomness to the process of selecting edges. These algorithms can provide approximate MSTs with high probability and can be useful in situations where exact solutions are not necessary.

• Boruvka-Chazelle Algorithm:

An improvement on Borůvka's algorithm that uses efficient data structures like Fibonacci heaps to achieve better time complexity for finding approximate MSTs.

The choice between these algorithms depends on factors such as the specific problem at hand, the characteristics of the graph (e.g., density), and performance considerations. While Prim's algorithm is known for its simplicity and efficiency in dense graphs, Kruskal's algorithm is often preferred for sparse graphs. Researchers and engineers select the most appropriate algorithm based on the problem's requirements and the available computational resources.

• Sensitivity to Edge Weights: Prim's algorithm assumes that edge weights are unique. If there are multiple edges with the same weight, the algorithm's behavior may be unpredictable, as it doesn't have a clear way to choose between equivalent edges. This can lead to different MSTs for graphs with duplicate edge weights.
• Inefficient for Sparse Graphs: In graphs where the number of vertices (V) is much larger than the number of edges (E), Prim's algorithm can be less efficient compared to other algorithms like Kruskal's algorithm, which has a better time complexity in such scenarios (O(E log E)).
• Not Suitable for Directed Graphs: Prim's algorithm is designed for undirected graphs. It cannot be directly applied to directed graphs, as it relies on the symmetry of undirected edges.
• Dependency on a Starting Vertex: The choice of the starting vertex can affect the resulting MST. While the overall structure of the MST remains the same, the specific edges in the MST may vary depending on the starting vertex. This dependency can be a drawback in certain situations where a unique MST is desired.
• Inefficient for Dynamic Graphs: If the graph is dynamic and edges are frequently added or removed, recomputing the entire MST using Prim's algorithm from scratch can be inefficient. Specialized algorithms designed for dynamic graphs may be more suitable in such cases.
• Lack of Parallelism: Prim's algorithm is inherently sequential, and its steps are not naturally parallelizable. In applications where parallel processing is essential, other algorithms or parallel variants may be more suitable.
• Memory Usage: The algorithm requires memory to store data structures like arrays, priority queues, or heaps. In some cases, the memory usage can be a limiting factor, especially for very large graphs.
• Limited to Connected Graphs: Prim's algorithm assumes that the input graph is connected. If the graph is not connected, the algorithm will find the minimum spanning tree for each connected component separately.
• Not Suitable for Negative Weight Edges: Prim's algorithm does not handle graphs with negative weight edges, as it assumes that all edge weights are non-negative. In such cases, algorithms like Dijkstra's algorithm or Bellman-Ford algorithm may be more appropriate.

Despite these disadvantages, Prim's algorithm remains a valuable tool for finding minimum spanning trees in various practical scenarios, especially when applied to dense graphs with unique edge weights and when computational efficiency is not a primary concern. Researchers and engineers should carefully consider the specific requirements of their problem and the characteristics of their data when choosing an algorithm for MST computation.

## Summary:

### Prim's Algorithm Overview:

• Prim's algorithm is a greedy algorithm used to find the Minimum Spanning Tree (MST) in a connected, undirected graph.
• The MST is a subset of the edges of the graph that connects all vertices while minimizing the total edge weight.
• Prim's algorithm incrementally builds the MST, starting from an initial vertex and adding vertices and edges one at a time until the MST is complete.

Key Steps in Prim's Algorithm:

Initialization:

• Choose an arbitrary starting vertex.
• Initialize data structures:
• key[]: Minimum edge weights required to connect each vertex to the MST. Initialize all values to infinity except the starting vertex (set to 0).
• parent[]: Stores the parent of each vertex in the MST. Initialize all values to -1.
• inMST[]: Tracks which vertices are included in the MST. Initialize all values to false.

Iterative Process:

Repeat the following steps until all vertices are included in the MST:

• Find the vertex u with the minimum key value among vertices not in the MST.
• Add u to the MST.
• Update the key values of adjacent vertices if they are not in the MST and if the edge weight to u is smaller than their current key value.
• Update the parent of adjacent vertices to u for the edges added in step c.
• Mark vertex u as included in the MST by setting inMST[u] to true.

Termination:

The algorithm terminates when all vertices are included in the MST.

Result:

The Minimum Spanning Tree (MST) is formed by the edges selected during the algorithm's execution.

Representation of the Graph:

The graph can be represented using an adjacency matrix or an adjacency list, depending on the specific implementation.

Applications:

• Prim's algorithm is used in various applications, including network design, clustering, and image segmentation.
• It's especially useful in scenarios where you want to connect a set of points (vertices) with minimum total edge weight.

In conclusion, Prim's algorithm is a fundamental method for finding the Minimum Spanning Tree in a graph. It efficiently constructs a tree that connects all vertices while minimizing the total edge weight. It's a valuable tool in various fields where optimization and efficient network design are required.