import java.util.Comparator;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Set;
//意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小
// undirected graph only
public class Code05_Prim {
public static class EdgeComparator implements Comparator<Edge> {
@Override
public int compare(Edge o1, Edge o2) {
return o1.weight - o2.weight;
}
}
public static Set<Edge> primMST(Graph graph) {
//解锁的边进入小根堆(优先队列)
PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(
new EdgeComparator());
HashSet<Node> set = new HashSet<>();
Set<Edge> result = new HashSet<>(); //依次挑选的前边在result里
for (Node node : graph.nodes.values()) { //随便挑选一个点
//如果set中不包含node,则将node加入set中
if (!set.contains(node)) {
set.add(node);
//获取node的所有边
for (Edge edge : node.edges) { //由一个点解锁所有相连的边
priorityQueue.add(edge);
}
//当小根堆不为空时
while (!priorityQueue.isEmpty()) {
//推出边edge,令toNode等于edge的出点
Edge edge = priorityQueue.poll();
Node toNode = edge.to;
//如果set中不包含了这个出点,就加入set中,同时将边edge加入结果集result
if (!set.contains(toNode)) {
set.add(toNode);
result.add(edge);
//遍历
for (Edge nextEdge : toNode.edges) {
priorityQueue.add(nextEdge);
}
}
}
}
}
return result;
}
// 请保证graph是连通图
// graph[i][j]表示点i到点j的距离,如果是系统最大值代表无路
// 返回值是最小连通图的路径之和
public static int prim(int[][] graph) {
int size = graph.length;
int[] distances = new int[size];
boolean[] visit = new boolean[size];
visit[0] = true;
for (int i = 0; i < size; i++) {
distances[i] = graph[0][i];
}
int sum = 0;
for (int i = 1; i < size; i++) {
int minPath = Integer.MAX_VALUE;
int minIndex = -1;
for (int j = 0; j < size; j++) {
if (!visit[j] && distances[j] < minPath) {
minPath = distances[j];
minIndex = j;
}
}
if (minIndex == -1) {
return sum;
}
visit[minIndex] = true;
sum += minPath;
for (int j = 0; j < size; j++) {
if (!visit[j] && distances[j] > graph[minIndex][j]) {
distances[j] = graph[minIndex][j];
}
}
}
return sum;
}
public static void main(String[] args) {
System.out.println("hello world!");
}
}
图——最小生成树(Prim算法)
最新推荐文章于 2025-08-24 21:29:33 发布