AcWing 859. Kruskal算法求最小生成树-java-基于并查集
原题链接
简单
作者:
Astarion
,
2021-02-15 22:43:42
,
所有人可见
,
阅读 260
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Main {
static class Edege implements Comparable<Edege> {
int start, end, weight;
public Edege(int start, int end, int weight) {
this.start = start;
this.end = end;
this.weight = weight;
}
@Override
public int compareTo(Edege o) {
return this.weight - o.weight;
}
}
//边数组存放所有边
static int n, m;
static int idx;
static List<Edege> edeges = new ArrayList<>();
//并查集存放已纳入生成树结点
static int[] p = new int[100010];
//当前集合的边权和
static int[] sum = new int[100010];
//当前集合的点数量
static int[] cnt = new int[100010];
static void insert(int a, int b, int w) {
//忽略自环
if (a == b) return;
edeges.add(new Edege(a, b, w));
}
//注意并查集写法
static int find(int x) {
if (p[x] != x) {
p[x] = find(p[x]);
}
return p[x];
}
static boolean kruskal() {
Collections.sort(edeges);
for (int i = 0; i < edeges.size(); i++) {
Edege edege = edeges.get(i);
//注意并查集用法
int a = find(edege.start);
int b = find(edege.end);
int w = edege.weight;
if ( a!= b) {
cnt[b] += cnt[a];
p[a] = b;
sum[b] += (sum[a] + w);
if (cnt[b] == n) return true;
}
}
return false;
}
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(isr);
String[] strs = in.readLine().split(" ");
n = Integer.parseInt(strs[0]);
m = Integer.parseInt(strs[1]);
for (int i = 1; i <= n; i++) {
p[i] = i;
cnt[i] = 1;
}
for (int i = 0; i < m; i++) {
strs = in.readLine().split(" ");
int a = Integer.parseInt(strs[0]);
int b = Integer.parseInt(strs[1]);
int w = Integer.parseInt(strs[2]);
insert(a, b, w);
}
in.close();
isr.close();
OutputStreamWriter osw = new OutputStreamWriter(System.out);
BufferedWriter out = new BufferedWriter(osw);
if (kruskal()) out.write(sum[find(1)] + "");
else out.write("impossible");
out.flush();
out.close();
osw.close();
}
}