小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图 中的最短路径。
小蓝的图由 2021 个结点组成,依次编号 1 至 2021。
对于两个不同的结点 a, b,如果 a 和 b 的差的绝对值大于 21,则两个结点 之间没有边相连;如果 a 和 b 的差的绝对值小于等于 21,则两个点之间有一条 长度为 a 和 b 的最小公倍数的无向边相连。
例如:结点 1 和结点 23 之间没有边相连;结点 3 和结点 24 之间有一条无 向边,长度为 24;结点 15 和结点 25 之间有一条无向边,长度为 75。
请计算,结点 1 和结点 2021 之间的最短路径长度是多少。
思路:
- 先初始化图,将有无向边的节点求出,a,b的最小公倍数为 a*b/gcd(a,b)
- floyd 算法求单源最短路径
- 注意这里试探的时候要处理越界的情况
public class 路径 {
public static void main(String[] args) {
// 建图
int x=1,y=2022;
int[][] map=new int[2022][2022];
for (int i = 1; i <2022; i++) {
for (int j = 1; j <2022; j++) {
if (i==j) {
map[i][j]=0;
continue;
}
if (Math.abs(i-j)>21) {
map[i][j]=Integer.MAX_VALUE;
continue;
}else {
map[i][j]=(i*j)/gcd(i,j);
}
}
}
// System.out.println(map[15][25]);
// map[i][j] 转化为 i,到j的最短路径
for (int k = 1; k < 2022; k++) {
for (int i = 1; i < 2022; i++) {
for (int j = 1; j < 2022; j++) {
if (map[i][k]!=Integer.MAX_VALUE&&map[k][j]!=Integer.MAX_VALUE) {
map[i][j]=Math.min(map[i][j], map[i][k]+map[k][j]);
}
}
}
}
System.out.println(map[1][2021]);
}
private static int gcd(int i, int j) {// j肯定不能为0做分母,为0时也不可能返回0
return j==0? i: gcd(j, i%j) ;
}
}
答案: