Minimum Spanning Tree using Priority Queue and Array List

Given a bi-directed weighted (positive) graph without self-loops, the task is to generate the minimum spanning tree of the graph.

Examples:

Input: N = 9, E = 14, edges = {{0, 1, 4}, {0, 7, 8}, {1, 2, 8}, {1, 7, 11}, {2, 3, 7}, {2, 8, 2}, {2, 5, 4}, {3, 4, 9}, {3, 5, 14}, {4, 5, 10}, {5, 6, 2}, {6, 7, 1}, {6, 8, 6}, {7, 8, 7}}
Output:
((A, B), Cost)
((6, 7), 1)
((6, 5), 2)
((1, 0), 4)
((2, 3), 7)
((5, 2), 4)
((3, 4), 9)
((2, 1), 8)
((2, 8), 2)
Example
An undirected graph consisting of all the vertices V and (V-1) edges has been generated



Input: N = 6, E = 14, edges = {{0, 2, 103}, {0, 1, 158}, {0, 2, 2}, {0, 5, 17}, {1, 3, 42}, {2, 4, 187}, {3, 0, 14}, {3, 2, 158}, {3, 5, 106}, {3, 4, 95}, {5, 1, 144}, {5, 2, 194}, {5, 3, 118}, {5, 3, 58}}
Output:
((A, B), Cost)
((0, 2), 2)
((0, 3), 14)
((0, 5), 17)
((3, 1), 42)
((3, 4), 95)

Approach

  • First, the edge having minimum cost/weight is found in the given graph.
  • The two initial vertices (vertex A, B of minimum cost edge) is added to visited/added set.
  • Now, all the connected edges with newly added vertex are added to priority queue.
  • The least cost vertex (add all the connected edges of pop vertex to priority queue) is popped from the priority queue and repeat until number of edges is equal to vertices-1.
  • By using priority queue time complexity will be reduced to (O(E log V)) where E is the number of edges and V is the number of vertices.
  • Pair class is also used to store the weights.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.io.*;
import java.util.*;
import java.lang.Comparable;
public class MST {
  
    // Pair class with implemented comparable
    static class Pair<U extends Comparable<U>,
                                V extends Comparable<V> >
        implements Comparable<Pair<U, V> > {
  
        public final U a;
        public final V b;
  
        private Pair(U a, V b)
        {
            this.a = a;
            this.b = b;
        }
  
        @Override
        public boolean equals(Object o)
        {
            if (this == o)
                return true;
            if (o == null || getClass() != o.getClass())
                return false;
  
            Pair<?, ?> pair = (Pair<?, ?>)o;
            if (!a.equals(pair.a))
                return false;
            return b.equals(pair.b);
        }
  
        // Overriding so that objects in map
        // could find the object key
        @Override
        public int hashCode()
        {
            return 31 * a.hashCode() + b.hashCode();
        }
  
        @Override
        public String toString()
        {
            return "(" + a + ", " + b + ")";
        }
  
        @Override
        public int compareTo(Pair<U, V> o)
        {
            return getV().compareTo(o.getV());
        }
        private U getU()
        {
            return a;
        }
        private V getV()
        {
            return b;
        }
    }
  
    static class Graph {
  
        int vertices;
        ArrayList[] edges;
  
        // This variable keeps the least cost edge
        static Pair<Pair<Integer, Integer>,
                    Integer>
            minCostEdge;
  
        Graph(int vertices)
        {
            minCostEdge = new Pair<>(new Pair<>(1, 1),
                                     Integer.MAX_VALUE);
            this.vertices = vertices;
            edges = new ArrayList[vertices + 1];
            for (int i = 0; i <= vertices; i++) {
                edges[i]
                    = new ArrayList<Pair<Integer, Integer> >();
            }
        }
  
        void addEdge(int a, int b, int weight)
        {
            edges[a].add(new Pair<>(b, weight));
  
            // Since its undirected, adding the
            // edges to both the vertices
            edges[b].add(new Pair<>(a, weight));
            if (weight < minCostEdge.b) {
                minCostEdge
                    = new Pair<>(new Pair<>(a, b), weight);
            }
        }
  
        void MST()
        {
  
            // Priority queue for applying heap
            PriorityQueue<Pair<Pair<Integer, Integer>,
                               Integer> >
                priorityQueue
                = new PriorityQueue<>();
  
            // Adding all the connected vertices
            // of MinCostEdge vertex A to PQ
            Iterator<Pair<Integer, Integer> > iterator
                = edges[minCostEdge.a.a].listIterator();
            while (iterator.hasNext()) {
                Pair<Integer, Integer> pair
                    = iterator.next();
                priorityQueue.add(
                    new Pair<>(
                        new Pair<>(minCostEdge.a.a, pair.a),
                        pair.b));
            }
  
            // Adding all the connected vertices
            // of MinCostEdge vertex B to PQ
            iterator = edges[minCostEdge.a.b].listIterator();
            while (iterator.hasNext()) {
                Pair<Integer, Integer> pair = iterator.next();
                priorityQueue.add(
                    new Pair<>(
                        new Pair<>(minCostEdge.a.b, pair.a),
                        pair.b));
            }
  
            // Set to check vertex is added or not
            Set<Integer> addedVertices = new HashSet<>();
  
            // Set contains all the added edges and cost from source
            Set<Pair<Pair<Integer, Integer>, Integer> > addedEdges
                = new HashSet<>();
  
            // Using the greedy approach to find
            // the least costing edge to the GRAPH
            while (addedEdges.size() < vertices - 1) {
  
                // Polling from priority queue
                Pair<Pair<Integer, Integer>, Integer> pair
                    = priorityQueue.poll();
  
                // Checking wether the vertex A is added or not
                if (!addedVertices.contains(pair.a.a)) {
                    addedVertices.add(pair.a.a);
                    addedEdges.add(pair);
  
                    // Adding all the connected vertices with vertex A
                    iterator = edges[pair.a.a].listIterator();
                    while (iterator.hasNext()) {
                        Pair<Integer, Integer> pair1
                            = iterator.next();
                        priorityQueue.add(
                            new Pair<>(
                                new Pair<>(pair.a.a, pair1.a),
                                pair1.b));
                    }
                }
  
                // Checking wether the vertex B is added or not
                if (!addedVertices.contains(pair.a.b)) {
                    addedVertices.add(pair.a.b);
                    addedEdges.add(pair);
  
                    // Adding all the connected vertices with vertex B
                    iterator = edges[pair.a.b].listIterator();
                    while (iterator.hasNext()) {
                        Pair<Integer, Integer> pair1
                            = iterator.next();
                        priorityQueue
                            .add(
                                new Pair<>(
                                    new Pair<>(pair.a.b, pair1.a),
                                    pair1.b));
                    }
                }
            }
  
            // Printing the MST
            Iterator<Pair<Pair<Integer, Integer>, Integer> > iterator1
                = addedEdges.iterator();
            System.out.println("((A"
                               + ", "
                               + "B)"
                               + ", "
                               + "Cost)");
            while (iterator1.hasNext()) {
                System.out.println(iterator1.next());
            }
        }
    }
  
    // Driver code
    public static void main(String[] args) throws IOException
    {
        // Initializing the graph
        Graph g = new Graph(9);
        g.addEdge(0, 1, 4);
        g.addEdge(0, 7, 8);
        g.addEdge(1, 2, 8);
        g.addEdge(1, 7, 11);
        g.addEdge(2, 3, 7);
        g.addEdge(2, 8, 2);
        g.addEdge(2, 5, 4);
        g.addEdge(3, 4, 9);
        g.addEdge(3, 5, 14);
        g.addEdge(4, 5, 10);
        g.addEdge(5, 6, 2);
        g.addEdge(6, 7, 1);
        g.addEdge(6, 8, 6);
        g.addEdge(7, 8, 7);
  
        // Appling MST
        g.MST();
    }
}

chevron_right


Output:

((A, B), Cost)
((6, 7), 1)
((6, 5), 2)
((1, 0), 4)
((2, 3), 7)
((5, 2), 4)
((3, 4), 9)
((2, 1), 8)
((2, 8), 2)




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.