试题 D :路径
类型:结果填空,总分:10分
【问题描述】
小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图中的最短路径。
小蓝的图由 2021 个结点组成,依次编号 1 至 2021。对于两个不同的结点 a, b,如果 a 和 b 的差的绝对值大于 21,则两个结点
之间没有边相连;如果 a 和 b 的差的绝对值小于等于 21,则两个点之间有一条长度为 a 和 b 的最小公倍数的无向边相连。
例如:结点 1 和结点 23 之间没有边相连;结点 3 和结点 24 之间有一条无向边,长度为 24;结点 15 和结点 25 之间有一条无向边,长度为 75。
请计算,结点 1 和结点 2021 之间的最短路径长度是多少。
【思路】
- 最短路径模板题,直接用朴素Dijkstra就行,挖坑俺有空再总结一下最短路算法
- 注意图的构造,求最大公约数和最小公倍数老熟人了
- 发现另一种思路大佬的dp做法
- 错误记录:在用邻接矩阵存图的时候,我们一般会用一个自定义的无穷大的数代表两点之间不连通,c/c++中一般会写
memset(dist, 0x3f, sizeof dist);
,我一开始考虑用Java的Integer.MAX_VALUE
代表无穷大,但是我忽略了这样就不能计算了,因为Integer.MAX_VALUE
随便加上一个数就超出int的表示范围结果就成负数(补码)了,所以注意无穷大还是得用static final int INF = 0x3f3f3f3f;
。0x3f3f3f3f
的优点有:十进制为1061109567
,和Integer.MAX_VALUE
一个数量级,即10^9
数量级,而一般场合下的数据都是小于10^9
的。0x3f3f3f3f * 2 = 2122219134
,我们定义的这个无穷大相加依然不会溢出。
【代码】
import java.util.Scanner;
import java.util.Arrays;
public class Main {
static final int INF = 0x3f3f3f3f;
static final int N = 2030;
static int[][] g = new int[N