Kruskal思想:将所有边排序,每次选最小的边,检查这个边两个顶点是否为同一个集合,不是的话就合并,是的话就不要(会形成回路),最后选n-1个边。选边的过程可以由堆进行优化
package com.yxs.graph1;
import java.io.BufferedInputStream;
import java.util.PriorityQueue;
import java.util.Scanner;
public class Kruskal {
static class Edge{
int to, w, from;
{
to = w = from = 0;
}
}
static final int MAXN = 105;
static int[] head = new int[MAXN];
static Edge[] edge = new Edge[MAXN];
static int len = 1;
static void add(int from, int to, int w) {
edge[len] = new Edge();
edge[len].from = from;
edge[len].to = to;
edge[len++].w = w;
}
static int[] parent = new int[MAXN];
static int[] tnums = new int[MAXN];
static {
for(int i = 0; i < parent.length;i++) {
parent[i] = i;
tnums[i] = 1;
}
}
static int getParent(int x) {
if(x == parent[x])return x;
else return parent[x] = getParent(parent[x]);
}
static boolean isSameset(int x, int y) {
int px = getParent(x);
int py = getParent(y);
if(px == py)return true;
return false;
}
static void union(int x, int y) {
int px = getParent(x);
int py = getParent(y);
if(px != py) {
if(tnums[px] <= tnums[py]) {
parent[px] = py;
tnums[py] += tnums[px];
}else {
parent[py] = px;
tnums[px] += tnums[py];
}
}
}
static void kruskal(int n) {//基于堆优化
PriorityQueue<Edge> queue = new PriorityQueue<>(
(x, y)->{
return x.w - y.w;
});
for(int i = 1;i < len;i++) {
queue.add(edge[i]);
}
int ans = 0, cnt = 0;
while(!queue.isEmpty() && cnt != n-1) {
Edge e = queue.poll();
if(!isSameset(e.from,e.to)) {
ans+=e.w;
cnt++;
union(e.from,e.to);
}
}
System.out.println("最小生成树的权值为:" + ans);
}
public static void main(String[] args) {
Scanner in = new Scanner(new BufferedInputStream(System.in));
int n = in.nextInt();
int e = in.nextInt();
for(int i = 1;i <= e;i++) {
int from = in.nextInt();
int to = in.nextInt();
int w = in.nextInt();
add(from, to, w);
}
kruskal(n);
}
}
/*
6 8
1 6 100
1 5 30
1 3 10
2 3 5
3 4 50
4 6 10
5 4 20
5 6 60
*/