解法一:Kruskal算法
思路
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] strs = reader.readLine().split(" ");
final int n = Integer.parseInt(strs[0]);
final int m = Integer.parseInt(strs[1]);
Point[] points = new Point[n + 1];
for (int i = 1; i <= n; ++i) {
points[i] = new Point(i);
}
Line[] lines = new Line[m];
Comparator<Line> lineComparator = new Comparator<Line>() {
@Override
public int compare(Line o1, Line o2) {
return Integer.compare(o1.val, o2.val);
}
};
for (int i = 0; i < m; ++i) {
strs = reader.readLine().split(" ");
lines[i] = new Line(Integer.parseInt(strs[0]), Integer.parseInt(strs[1]), Integer.parseInt(strs[2]));
}
Arrays.sort(lines, lineComparator);
int[] ans = new int[n - 1];
int index = 0;
for (int i = 0, u, v; i < m; ++i) {
u = lines[i].u;
v = lines[i].v;
if (union(points[u], points[v])) {
ans[index++] = i;
if (index == n - 1) {
break;
}
}
}
if (index < n - 1) {
System.out.println(-1);
} else {
int sum = 0;
for (int i : ans) {
// System.out.println(lines[i]);
sum += lines[i].val;
}
System.out.println(sum);
}
}
private static boolean union(Point u, Point v) {
Point uMaster = u.getOrigin();
Point vMaster = v.getOrigin();
if (uMaster == vMaster) {
return false;
}
uMaster.master = vMaster;
return true;
}
}
class Point {
int id;
// 标识是否在同一棵树上
Point master;
public Point getOrigin() {
master = _getOrigin(this);
return master;
}
private Point _getOrigin(Point p) {
if (p != p.master) {
p.master = _getOrigin(p.master);
}
return p.master;
}
public Point(int id) {
this.id = id;
master = this;
}
}
class Line {
int u;
int v;
int val;
public Line(int u, int v, int val) {
this.u = u;
this.v = v;
this.val = val;
}
@Override
public String toString() {
return "Line{" +
"u=" + u +
", v=" + v +
", val=" + val +
'}';
}
}
解法二:Prime算法
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] strs = reader.readLine().split(" ");
final int n = Integer.parseInt(strs[0]);
final int m = Integer.parseInt(strs[1]);
Point[] points = new Point[n + 1];
for (int i = 1; i <= n; ++i) {
points[i] = new Point(i);
}
int[][] graph = new int[n + 1][n + 1];
for (int i = 1; i <= n; ++i) {
Arrays.fill(graph[i], Integer.MAX_VALUE);
graph[i][i] = 0;
}
for (int i = 0, u, v, val; i < m; ++i) {
strs = reader.readLine().split(" ");
u = Integer.parseInt(strs[0]);
v = Integer.parseInt(strs[1]);
val = Integer.parseInt(strs[2]);
graph[u][v] = val;
graph[v][u] = val;
}
for (int i = 1; i <= n; ++i) {
points[i].dis = graph[i][1];
}
List<Point> undoList = new LinkedList<>();
for (int i = 2; i <= n; ++i) {
undoList.add(points[i]);
}
int[] ans = new int[n - 1];
int index = 0;
for (int i = 0; i < n - 1; ++i) {
Point min = new Point(0);
min.dis = Integer.MAX_VALUE;
for (Point p : undoList) {
if (p.dis < min.dis) {
min = p;
}
}
if (min.dis == Integer.MAX_VALUE) {
System.out.println(-1);
return;
}
ans[index++] = min.dis;
int minIndex = min.id;
for (Iterator<Point> iter = undoList.iterator(); iter.hasNext(); ) {
Point tmp = iter.next();
if (tmp.equals(min)) {
iter.remove();
} else {
tmp.dis = Math.min(tmp.dis, graph[minIndex][tmp.id]);
}
}
}
int sum = 0;
for (int i : ans) {
sum += i;
}
System.out.println(sum);
}
}
class Point {
int id;
int dis;
public Point(int id) {
this.id = id;
dis = 0;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return id == point.id;
}
}
解法三:Prime算法+堆优化
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] strs = reader.readLine().split(" ");
final int n = Integer.parseInt(strs[0]);
final int m = Integer.parseInt(strs[1]);
Point[] points = new Point[n + 1];
for (int i = 1; i <= n; ++i) {
points[i] = new Point(i);
}
for (int i = 0, u, v, val; i < m; ++i) {
strs = reader.readLine().trim().split(" ");
u = Integer.parseInt(strs[0]);
v = Integer.parseInt(strs[1]);
val = Integer.parseInt(strs[2]);
points[u].nextList.add(new int[]{v, val});
points[v].nextList.add(new int[]{u, val});
}
Comparator<int[]> comparator = new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return Integer.compare(o1[1], o2[1]);
}
};
Queue<int[]> queue = new PriorityQueue<>(comparator);
points[1].isVisited = true;
queue.addAll(points[1].nextList);
int[] ans = new int[n - 1];
int index = 0;
while ((!queue.isEmpty()) && (index < n - 1)) {
int[] min = queue.poll();
if (points[min[0]].isVisited) {
continue;
}
points[min[0]].isVisited = true;
ans[index++] = min[1];
for (int[] pair:points[min[0]].nextList){
if (!points[pair[0]].isVisited){
queue.add(pair);
}
}
}
if (index < n - 1) {
System.out.println(-1);
} else {
int sum = 0;
for (int i : ans) {
// System.out.println(i);
sum += i;
}
System.out.println(sum);
}
}
}
class Point {
int id;
boolean isVisited;
List<int[]> nextList;
public Point(int id) {
this.id = id;
isVisited = false;
nextList = new ArrayList<>(id);
}
}