【图的应用】最小生成树
题目链接 :最小生成树_牛客题霸_牛客网 (nowcoder.com)

分析采用Prim算法,使用一个Set集合存储已经选择的节点、使用一个Map存储每个节点相关联的边Edge的信息,其中边使用一个ArrayList来存储Edge
在选择边之前,将每条边存储到优先队列中,根据优先队列的保证每次取出的都是最小的一条
1 import java.util.*; 2 public class Solution { 3 /** 4 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 5 * 6 * 返回最小的花费代价使得这n户人家连接起来 7 * @param n int n户人家的村庄 8 * @param m int m条路 9 * @param cost int二维数组 一维3个参数,表示连接1个村庄到另外1个村庄的花费的代价 10 * @return int 11 */ 12 // 定义边结构 13 static class Edge{ 14 int from; 15 int to; 16 int w; 17 public Edge(int from,int to,int w){ 18 this.from = from; 19 this.to = to; 20 this.w = w; 21 } 22 } 23 public int miniSpanningTree (int n, int m, int[][] cost) { 24 // write code here 25 // Set存储最小生成树中的顶点集合 26 Set<Integer> set = new HashSet<>(); 27 // Map存储每个节点关联的边 28 Map<Integer,List<Edge>> map = new HashMap<>(); 29 // 初始化Map 30 for(int i=0;i<n;i++){ 31 List<Edge> l = new ArrayList<>(); 32 map.put(i+1,l); 33 } 34 // 填充Map 35 for(int i=0;i<m;i++){ 36 Edge edge = new Edge(cost[i][0],cost[i][1],cost[i][2]); 37 map.get(cost[i][0]).add(edge); 38 map.get(cost[i][1]).add(edge); 39 } 40 int sum = 0; 41 set.add(1); 42 // 优先队列用来找出最小的边 43 PriorityQueue<Edge> queue = new PriorityQueue<>(new Comparator<Edge>(){ 44 public int compare(Edge o1,Edge o2){ 45 return o1.w-o2.w; 46 } 47 }); 48 for(Edge edge:map.get(1)){ 49 queue.add(edge); 50 } 51 while(!queue.isEmpty()){ 52 Edge edge = queue.poll(); 53 if(!set.contains(edge.from) || !set.contains(edge.to)){ 54 // 找到待添加的节点 55 int verx = set.contains(edge.from) ? edge.to:edge.from; 56 set.add(verx); 57 sum += edge.w; 58 for(Edge edge1: map.get(verx)){ 59 queue.add(edge1); 60 } 61 } 62 } 63 return sum; 64 } 65 }

浙公网安备 33010602011771号