import java.util.Arrays;
public class 路径 {
static final int MAX_NODE = 2021; // 定义常量MAX_NODE,表示图中的最大节点数
static final long INF = Long.MAX_VALUE; // 定义常量INF,表示无穷大,用于初始化距离数组
// 方法:计算两数的最大公约数(GCD)
private static long gcd(long a, long b) {
if (b == 0) return a; // 递归的基本情况,当b为0时返回a
return gcd(b, a % b); // 使用欧几里得算法递归计算GCD
}
// 方法:计算两数的最小公倍数(LCM)
private static long lcm(long a, long b) {
return (a / gcd(a, b)) * b; // 计算最小公倍数:乘积除以最大公约数
}
// 使用Dijkstra算法计算从节点1到节点2021的最短路径
public static long findShortestPath() {
// distances数组,存储从源点到每个点的最短距离
long[] distances = new long[MAX_NODE + 1]; // 创建距离数组,大小为MAX_NODE + 1
Arrays.fill(distances, INF); // 初始化所有距离为无穷大
distances[1] = 0; // 将起点到自身的距离设置为0
boolean[] visited = new boolean[MAX_NODE + 1]; // 创建一个标记数组,用于记录节点是否已访问
for (int i = 0; i < MAX_NODE; i++) { // 遍历所有节点
// 找到当前未访问的距离最小的节点
long minDistance = INF;
int minIndex = -1;
for (int j = 1; j <= MAX_NODE; j++) {
if (!visited[j] && distances[j] < minDistance) {
minDistance = distances[j];
minIndex = j;
}
}
if (minIndex == -1) break; // 所有可达节点都访问过了,则退出循环
visited[minIndex] = true; // 标记当前节点为已访问
// 更新当前节点相邻节点的距离
for (int j = 1; j <= MAX_NODE; j++) { // 遍历所有节点
if (Math.abs(minIndex - j) <= 21) { // 如果节点间差的绝对值小于等于21
long edgeWeight = lcm(minIndex, j); // 计算这两个节点之间边的权重(最小公倍数)
if (!visited[j] && distances[j] > distances[minIndex] + edgeWeight) {
distances[j] = distances[minIndex] + edgeWeight; // 更新最短距离
}
}
}
}
return distances[MAX_NODE]; // 返回从节点1到节点2021的最短路径长度
}
public static void main(String[] args) { // 主函数
System.out.println(findShortestPath()); // 调用findShortestPath方法并打印结果
}
}
0 回复
0 转发
0 喜欢
7 阅读



