题解 | #最小生成树#
最小生成树
https://www.nowcoder.com/practice/735a34ff4672498b95660f43b7fcd628
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 返回最小的花费代价使得这n户人家连接起来
* @param n int整型 n户人家的村庄
* @param m int整型 m条路
blank * @param cost int整型二维数组 一维3个参数,表示连接1个村庄到另外1个村庄的花费的代价
* @return int整型
*/
//边的定义
static class Edge {
int src;
int dest;
int weight;
public Edge(int src, int dest, int weight) {
this.src = src;
this.dest = dest;
this.weight = weight;
}
}
//prime算法实现
public int miniSpanningTree(int n, int m, int[][] cost) {
int[][] doubleCost = new int[2 * m][3];
int i = 0;
for (int[] c : cost) {
doubleCost[i] = c;
doubleCost[i + 1][0] = c[1];
doubleCost[i + 1][1] = c[0];
doubleCost[i + 1][2] = c[2];
i += 2;
}
//贪心算法,局部最优
//起始节点集合与目的节点集合
Set<Integer> srcSet = new HashSet<>();
//初始化两个集合
srcSet.add(1);
//从srcSet到destSet集合的边
//定义优先级队列与初始优先级队列
PriorityQueue<Edge> minHeap = new PriorityQueue<>(
Comparator.comparingInt(a -> a.weight)
);
for (int[] c : doubleCost) {
if (c[0] == 1) {
minHeap.offer(new Edge(1, c[1], c[2]));
}
}
int retWeight = 0;
while (!minHeap.isEmpty()) {
Edge minEdge = minHeap.poll();
int dest = minEdge.dest;
//判断dest是否被标记过
if (!srcSet.contains(dest)) {
retWeight += minEdge.weight;
//目的节点被标记:加入srcSet
srcSet.add(dest);
//添加新增起始顶点的所有直接连通的边
for (int[] c : doubleCost) {
if (c[0] == dest) {
minHeap.offer(new Edge(dest, c[1], c[2]));
}
}
}
}
return retWeight;
}
}
查看2道真题和解析
字节跳动公司福利 1309人发布