寻宝
寻宝
题目描述
亮亮解出了卷轴隐藏的秘密,来到了一片沼泽地。这里有很多空地,而面试直通卡可能埋在任意一块空地中,好在亮亮发现了一堆木材,他可以将木材铺在两个空地之间的沼泽地上。因为亮亮不知道面试直通卡具体在哪一块空地中,所以必须要保证任意一块空地对于亮亮来说是可以抵达的。 “怎么还有鳄鱼!没办法,看来有些空地不能直接到达了。” 亮亮虽然没有洁癖,但是沼泽地实在太臭了,所以亮亮不会循环利用木材。而且木材不能拼接在一起使用,所以亮亮必须要知道在耗费木材最少的情况下,最长的那根木材至少需要多长。
输入描述:
第一行包含两个整数N(1≤N≤10000),M(1≤M≤1000000)。N表示公有N块空地。
接下来M行,每行包含三个整数P(1≤P≤N),Q(1≤Q≤N),K代表P,Q两个间没有鳄鱼,需要耗费K的木材。
输出描述:
一个整数,即耗费木材最少的情况下,最长的那根木材长度。
示例1
输入
[复制](javascript:void(0)😉
4 3<br/>1 2 1<br/>2 3 1<br/>3 4 2<br/>
输出
[复制](javascript:void(0)😉
2
本题是典型的最小生成树问题。事实证明最小生成树还是好写的:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
if(num<=1){
System.out.println(0);
return;
}
int[][] matrix = new int[num][num];
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
if (i == j) {
matrix[i][j] = 0;
} else {
matrix[i][j] = Integer.MAX_VALUE;
}
}
}
int roads = sc.nextInt();
if(roads<=0){
System.out.println(0);
return;
}
for (int i = 0; i < roads; i++) {
int from = sc.nextInt();
int to = sc.nextInt();
int length = sc.nextInt();
matrix[from - 1][to - 1] = length;
matrix[to - 1][from - 1] = length;
}
//使用prim算法,因为每一个位置都是可达的,所以从0开始分析
int[] distance = new int[num];
int[] visited = new int[num];
visited[0] = 1;
int longest = 0;
int k = 0;
for (int i = 1; i < num; i++) {
distance[i] = matrix[0][i];//初始化,不能从1直接达到的就为Integer.MAX_VALUE
}
for (int j = 0; j < num - 1; j++) {//每次将一个点加入,所以一共n-1次
int min = Integer.MAX_VALUE;
for (int i = 0; i < num; i++) {
if (visited[i]==0 && distance[i] < min) {
min = distance[i];
k = i;
}
}
visited[k] = 1;
distance[k] = 0;//对于访问过的节点,设置其distance为0
longest = Math.max(longest, min);
for (int i = 0; i < num; i++) {
distance[i] = Math.min(distance[i], matrix[k][i]);//更新一下与新选择的节点相连的节点的距离
}
}
System.out.println(longest);
}
}
评测只过去了70%,说有数组越界,真的不知道是哪里