利用Python解决最短路径问题
题意
一图由 2021 个结点组成,依次编号 1 至 2021。
对于两个不同的结点 a, b,如果 a 和 b 的差的绝对值大于 21,则两个结点之间没有边相连;如果 a 和 b 的差的绝对值小于等于 21,则两个点之间有一条 长度为 a 和 b 的最小公倍数的无向边相连。
例如:结点 1 和结点 23 之间没有边相连;结点 3 和结点 24 之间有一条无向边,长度为 24;结点 15 和结点 25 之间有一条无向边,长度为 75。
请计算,结点 1 和结点 2021 之间的最短路径长度是多少。
运行限制
最大运行时间:1s
最大运行内存: 128M
解题思路
代码
法一(基于最短路径长度递增):
import math
def lcm(x,y):
return x*y//math.gcd(x,y)
n = 2021
dp = [float('inf')]*(n+1)
dp[1]=0
for i in range(1,n):
for j in range(i+1,i+22):
if j>n:
break
dp[j] = min(dp[j],dp[i]+lcm(i,j))
print(dp[n])
法二(基于图论中的最短路径算法):
import math
def lcm(a, b):
return int(a * b / math.gcd(a, b))
n = 2021
g = [[0 for i in range(1, n + 2)] for j in range(1, n + 2)]
for i in range(1, n + 1):
for j in range(1, n + 1):
if i == j:
g[i][j] = g[j][i] = 0
elif abs(i - j) <= 21:
g[i][j] = g[j][i] = lcm(i, j)
else:
g[i][j] = 1000000000
for k in range(1, n + 1):
for i in range(1, n + 1):
for j in range(1, n + 1):
if g[i][j] > g[i][k] + g[k][j]:
g[i][j] = g[i][k] + g[k][j]
print(g[1][n])
推荐练习
算法的学习还是要多以练习为主,想要练习python编程的算法的同学,推荐可以去牛客网(点击可直达)看看,他们现在的IT题库内容很丰富,属于国内做的很好的了,而且是课程+刷题+面经+求职+讨论区分享,里面的资源也是全部免费的。
他们这个python的练习题,知识点编排详细,题目安排合理,题目表述以指导的形式进行。整个题单覆盖了Python入门的全部知识点以及全部语法,通过知识点分类逐层递进,从Hello World开始到最后的实践任务,都会非常详细地指导你应该使用什么函数,应该怎么输入输出,到后面的算法练习也是,非常推荐大家在里面练习。