写出最小生成树(克鲁斯卡尔)的模板,使用java语言和优先队列
时间: 2023-11-29 15:54:07 浏览: 86
Java代码如下:
```
import java.util.*;
class Edge implements Comparable<Edge>{
int u; // 起点
int v; // 终点
int w; // 权重
public Edge(int u, int v, int w) {
this.u = u;
this.v = v;
this.w = w;
}
@Override
public int compareTo(Edge o) {
return Integer.compare(this.w, o.w); // 按照权重从小到大排序
}
}
public class Kruskal {
static int MAXN = 10005; // 最大顶点数
static int[] father = new int[MAXN]; // 并查集数组
static PriorityQueue<Edge> pq = new PriorityQueue<Edge>(); // 优先队列
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 顶点数
int m = sc.nextInt(); // 边数
// 初始化并查集
for(int i = 1; i <= n; i++) {
father[i] = i;
}
// 读入边
for(int i = 1; i <= m; i++) {
int u = sc.nextInt();
int v = sc.nextInt();
int w = sc.nextInt();
pq.offer(new Edge(u, v, w)); // 将边加入优先队列
}
int res = 0; // 最小生成树的权值和
// Kruskal算法
while(!pq.isEmpty()) {
Edge e = pq.poll(); // 取出当前最小的边
int fu = find(e.u);
int fv = find(e.v);
if(fu != fv) { // 如果两个顶点不在同一个集合中,则加入最小生成树
father[fu] = fv; // 合并两个集合
res += e.w;
}
}
System.out.println(res); // 输出最小生成树的权值和
}
// 并查集查找操作
static int find(int x) {
if(father[x] == x) {
return x;
} else {
return father[x] = find(father[x]);
}
}
}
```
其中,`Edge`类表示边,包括起点、终点和权重。`pq`是优先队列,用于存储边并按照权重从小到大排序。`father`数组是并查集数组,用于维护顶点之间的连通性。`find`函数是并查集的查找操作,用于查找顶点所在的集合。在主函数中,首先读入顶点数和边数,然后读入每条边并加入优先队列。接下来,按照克鲁斯卡尔算法的流程,不断从优先队列中取出最小的边,判断其所连接的两个顶点是否在同一个集合中,如果不在,则将它们合并,并加入最小生成树。最后输出最小生成树的权值和即可。
阅读全文