利用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开始到最后的实践任务,都会非常详细地指导你应该使用什么函数,应该怎么输入输出,到后面的算法练习也是,非常推荐大家在里面练习。

在这里插入图片描述

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python中,可以使用Dijkstra算法来找到最短路径。Dijkstra算法使用优先队列来寻找未知顶点中具有最小dist值的顶点。首先,需要实现一个Vertex类,并在该类中实现__lt__方法,以支持小于比较运算符。然后,可以使用递归的思想来实现找到最短路径的函数。下面是一个示例代码: ```python import heapq class Vertex: def __init__(self, name): self.name = name self.dist = float('inf') self.prev = None def __lt__(self, other): return self.dist < other.dist def find_shortest_path(start, end): pq = \[\] start.dist = 0 heapq.heappush(pq, start) while pq: current = heapq.heappop(pq) if current == end: break for neighbor in current.neighbors: distance = current.dist + current.get_distance(neighbor) if distance < neighbor.dist: neighbor.dist = distance neighbor.prev = current heapq.heappush(pq, neighbor) path = \[\] current = end while current: path.append(current.name) current = current.prev path.reverse() return path ``` 这段代码使用了优先队列来实现Dijkstra算法,通过不断更新顶点的dist值和prev指针来找到最短路径。你可以将起点和终点作为参数传递给`find_shortest_path`函数,它将返回一个包含最短路径顶点名称的列表。 #### 引用[.reference_title] - *1* *2* [最短路径算法——Dijkstra算法——python3实现](https://blog.csdn.net/anlian523/article/details/80893372)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [利用Python解决最短路径问题](https://blog.csdn.net/Eric005/article/details/123521781)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啥都鼓捣的小yao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值