第一波尝试
思路:Kruskal算法求最小生成树
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
class Node{
int u;
int v;
int dis;
public Node(int u, int v, int dis) {
super();
this.u = u;
this.v = v;
this.dis = dis;
}
@Override
public String toString() {
return "Node [u=" + u + ", v=" + v + ", dis=" + dis + "]";
}
}
public class Main {
public static void main(String[] args){
Scanner s = new Scanner(System.in);
int n = s.nextInt(); // 节点数
int m = s.nextInt(); // 边数
int root = s.nextInt()-1; // 根节点
ArrayList<Node> nodes = new ArrayList<Node>();
// 输入
int u,v,t;
for(int i=0;i<m;i++) {
u = s.nextInt()-1;
v = s.nextInt()-1;
t = s.nextInt();
nodes.add(new Node(u,v,t));
}
// 排序
Collections.sort(nodes, new Comparator<Node>() {
public int compare(Node o1, Node o2) {
return o1.dis-o2.dis;
}
});
// 构建最小生成树
// 初始化并查集
int[] ufset = new int[n];
for(int i=0;i<n;i++) {
ufset[i] = i;
}
// 从小到大处理边
int cnt = 0; // 总共应合并n-1次
for(Node node:nodes) {
int uroot = find(ufset,node.u);
int vroot = find(ufset,node.v);
if(uroot != vroot) {
ufset[vroot] = uroot;
cnt++;
if(cnt==n-1) {
System.out.println(node.dis);
break;
}
}
}
}
// 找根节点,并压缩路径
public static int find(int[] ufset,int index) {
// System.out.println("find"+index);
int root = ufset[index];
while(ufset[root]!=root) {
root = ufset[root];
}
while(index!=root) {
int next = ufset[index];
ufset[index] = root;
index = next;
}
// System.out.println("root"+root);
return root;
}
}
结果:90分,超时
第二波尝试
修改了存结点的方式
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner s = new Scanner(System.in);
int n = s.nextInt(); // 节点数
int m = s.nextInt(); // 边数
int root = s.nextInt()-1; // 根节点
// 输入
ArrayList<int[]> nodeArr = new ArrayList<int[]>();
for(int i=0;i<m;i++) {
int[] nums = new int[3];
nums[0] = s.nextInt()-1;
nums[1] = s.nextInt()-1;
nums[2] = s.nextInt();
nodeArr.add(nums);
}
// 排序
Collections.sort(nodeArr, new Comparator<int[]>(){
public int compare(int[] o1,int[] o2) {
return o1[2]-o2[2];
}
}
);
// 构建最小生成树
// 初始化并查集
int[] ufset = new int[n];
for(int i=0;i<n;i++) {
ufset[i] = i;
}
// 从小到大处理边
int cnt = 0; // 总共应合并n-1次
for(int[] node:nodeArr) {
int uroot = find(ufset,node[0]);
int vroot = find(ufset,node[1]);
if(uroot != vroot) {
ufset[vroot] = uroot;
cnt++;
if(cnt==n-1) {
System.out.println(node[2]);
break;
}
}
}
}
// 找根节点,并压缩路径
public static int find(int[] ufset,int index) {
int root = ufset[index];
while(ufset[root]!=root) {
root = ufset[root];
}
while(index!=root) {
int next = ufset[index];
ufset[index] = root;
index = next;
}
return root;
}
}
结果:得分100,时间使用 1.0s,空间使用 107.7MB
踩点过嘿嘿
测试1
输入
4
5
1
1 2 3
1 3 4
1 4 5
2 3 8
3 4 2
输出
4
测试2
输入
6
10
1
1 2 10
1 3 16
1 4 14
2 4 15
3 4 14
2 3 24
4 5 23
4 6 8
3 6 16
5 6 22
输出
22
测试3
输入
6
9
1
1 2 1
3 5 2
4 6 3
2 5 4
1 3 5
1 4 6
3 4 7
2 3 8
5 6 9
输出
6