1、问题描述
小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图中的最短路径。
小蓝的图由 2021 个结点组成,依次编号 1至 2021。对于两个不同的结点 a , b,如果 a 和 b 的差的绝对值大于 21 ,则两个结点之间没有边相连;如果 a 和 b的差的绝对值小于等于 21 ,则两个点之间有一条长度为 a和 b的最小公倍数的无向边相连。
例如:结点 1 和结点 23 之间没有边相连;结点 3 和结点 24 之间有一条无向边,长度为 24 ;结点 15和结点 25 之间有一条无向边,长度为 75 。
请计算,结点 1 和结点 2021 之间的最短路径长度是多少。
提示:建议使用计算机编程解决问题。
2、代码实现
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[][] graph = new int[2022][2022];
for(int i = 1;i < graph.length;i++) {
for(int j = 1;j < graph[i].length;j++) {
if(i != j && Math.abs(i - j) > 21) {
graph[i][j] = 99999999;
graph[j][i] = 99999999;
}else if(i != j && Math.abs(i - j) <= 21){
graph[i][j] = i * j / max(i,j);
graph[j][i] = i * j / max(i,j);
}
}
}
for(int i = 1;i < graph.length;i++) {
graph[i][i] = 0;
}
//打印局部数据
// for(int i = 1;i < 25;i++) {
// for(int j = 1;j < 25;j++) {
// System.out.print(graph[i][j] + "\t");
// }
// System.out.println();
// }
int[] dist = dijkstra(graph,1);
System.out.println(dist[2021]);
}
//最大公因数
public static int max(int a,int b) {
if(a % b == 0) {
return b;
}
return max(b,a % b);
}
//迪杰斯特拉算法,这个方法不理解了可以看看我的其他文章,有专门讲迪杰斯特拉算法的,非常通透
public static int[] dijkstra(int[][] graph,int start) {
int n = graph.length;
int[] visit = new int[n];
int[] dist = new int[n];
for(int i = 1;i < n;i++) {
dist[i] = graph[start][i];
}
visit[start] = 1;
for(int i = 1;i < n;i++){
int min_dist = 99999999;
int middle = 1;
for(int j = 1;j < n;j++) {
if(visit[j] == 0 && min_dist > dist[j]) {
min_dist = dist[j];
middle = j;
}
}
for(int j = 1;j < n;j++) {
if(visit[j] == 0 && dist[j] > dist[middle] + graph[middle][j]) {
dist[j] = dist[middle] + graph[middle][j];
}
}
visit[middle] = 1;
}
return dist;
}
}