CSDN
package com.zhang.reflection.面试.算法模版.图.最小生成树;
import java.util.*;
/**
* 最小生成树,从点的角度考虑,从那个点出发都行
*/
public class Prim {
//图
static class Graph{
//点集<编号,实际的点>
public HashMap<Integer, Node> nodes;
//边集
public HashSet<Edge> edges;
public Graph(){
nodes=new HashMap<>();
edges=new HashSet<>();
}
}
//点
static class Node{
//点上的值
public int value;
//点的入度
public int in;
//点的出度
public int out;
//相邻节点集,以该节点为起点
public ArrayList<Node> nexts;
//相邻边集,以该节点为起点
public ArrayList<Edge> edges;
public Node(int value){
this.value=value;
in=0;
out=0;
nexts=new ArrayList<>();
edges=new ArrayList<>();
}
}
//边
static class Edge{
//边得权值
public int weight;
//边的起点
public Node from;
//边的终点
public Node to;
public Edge(int weight, Node from, Node to){
this.weight=weight;
this.from=from;
this.to=to;
}
}
//比较器
public static class EdgeCompator implements Comparator<Edge> {
@Override
public int compare(Edge o1, Edge o2) {
return o1.weight - o2.weight;
}
}
//普里姆算法
public static Set<Edge> primMST(Graph graph) {
HashSet<Node> set = new HashSet<>();//标记作用
PriorityQueue<Edge> priorityQueue = new PriorityQueue<Edge>(new EdgeCompator());
HashSet<Edge> res = new HashSet<>();
//针对森林结构
for (Node node : graph.nodes.values()) {
if (!set.contains(node)) {
set.add(node);
priorityQueue.addAll(node.edges);
while (!priorityQueue.isEmpty()) {
Edge poll = priorityQueue.poll();
Node toNode = poll.to;
if (!set.contains(toNode)) {
res.add(poll);
set.add(toNode);
priorityQueue.addAll(toNode.edges);
}
}
}
}
return res;
}
}