📜  使用优先队列和数组列表的最小生成树

📅  最后修改于: 2021-10-25 05:15:36             🧑  作者: Mango

给定一个没有自环的双向加权(正)图,任务是生成图的最小生成树。
例子:

方法

  • 首先,在给定的图中找到具有最小成本/权重的边。
  • 将两个初始顶点(最小成本边的顶点 A、B)添加到访问/添加集。
  • 现在,所有具有新添加顶点的连接边都被添加到优先级队列中。
  • 成本最低的顶点(将弹出顶点的所有连接边添加到优先级队列)从优先级队列中弹出并重复,直到边数等于 vertices-1。
  • 通过使用优先级队列,时间复杂度将降低到(O(E log V)) ,其中 E 是边数,V 是顶点数。
  • Pair 类也用于存储权重。

下面是上述方法的实现:

Java
// 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,
                                V extends Comparable >
        implements Comparable > {
 
        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 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,
                    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 >();
            }
        }
 
        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,
                               Integer> >
                priorityQueue
                = new PriorityQueue<>();
 
            // Adding all the connected vertices
            // of MinCostEdge vertex A to PQ
            Iterator > iterator
                = edges[minCostEdge.a.a].listIterator();
            while (iterator.hasNext()) {
                Pair 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 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 addedVertices = new HashSet<>();
 
            // Set contains all the added edges and cost from source
            Set, 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, Integer> pair
                    = priorityQueue.poll();
 
                // Checking whether 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 pair1
                            = iterator.next();
                        priorityQueue.add(
                            new Pair<>(
                                new Pair<>(pair.a.a, pair1.a),
                                pair1.b));
                    }
                }
 
                // Checking whether 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 pair1
                            = iterator.next();
                        priorityQueue
                            .add(
                                new Pair<>(
                                    new Pair<>(pair.a.b, pair1.a),
                                    pair1.b));
                    }
                }
            }
 
            // Printing the MST
            Iterator, 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();
    }
}


输出:
((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)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程