最短路径问题(Dijkstra解法)

本文介绍了使用Dijkstra算法解决最短路径问题的方法,包括算法原理、基本步骤、数据结构以及算法的时间复杂度。通过不断扩充一个包含已知最短路径顶点的集合,最终找到起点到所有顶点的最短路径。代码实现参考了hdu2544题目。
摘要由CSDN通过智能技术生成

算法分类:

贪心


算法原理:

设置一个顶点的集合s,并不断地扩充这个集合,一个顶点属于集合s当且仅当从源点到该点的路径已求出。开始时s中仅有源点,并且调整非s中点的最短路径长度,找当前最短路径点,将其加入到集合s,直到终点在s中。
基本步骤:
1、把所有结点分成两组:
       第一组:包括已经确定最短路径的结点;
       第二组:包括尚未确定最短路径的结点。
2、开始时,第一组只包含起点,第二组包含剩余的点;
3、用贪心的策略,按最短路径长度递增的顺序把第二组的结点加到第一组去,直到v0可达的所有结点都包含于第一组中。在这个过程中,不断更新最短路径,总保持从v0到第一组各结点的最短路径长度dist都不大于从v0到第二组任何结点的路径长度。
4、每个结点对应一个距离值,第一组结点对应的距离就是v0到此结点的最短路径长度,第二组结点对应的距离值就是v0由第一组结点到此结点的最短路径长度。
5、直到所有的顶点都扫描完毕(v0可达的所有结点都包含于第一组中),找到v0到其它各点的所有最短路径。

如图:求0点到其他点的最短路径。

以下是使用Python实现Dijkstra算法求解最短路径的示例代码: ```python import heapq def dijkstra(graph, start): # 初始化距离字典,将起点到起点的距离设为0,其余为无穷大 distances = {vertex: float('inf') for vertex in graph} distances[start] = 0 # 初始化堆和visited集合 heap = [(0, start)] visited = set() while heap: # 取出堆中距离最小的节点 (current_distance, current_vertex) = heapq.heappop(heap) # 如果该节点已经被访问过,则跳过 if current_vertex in visited: continue # 将该节点标记为已访问 visited.add(current_vertex) # 遍历该节点的所有邻居节点 for neighbor, weight in graph[current_vertex].items(): # 计算起点到该邻居节点的距离 distance = current_distance + weight # 如果该距离比已有的距离更小,则更新距离字典 if distance < distances[neighbor]: distances[neighbor] = distance # 将该邻居节点加入堆中 heapq.heappush(heap, (distance, neighbor)) # 返回距离字典 return distances ``` 其中,`graph`是一个字典,表示图的邻接表,`start`是起点。字典中的每个键表示一个节点,对应的值是一个字典,表示该节点的所有邻居节点及其边权重。 以下是一个示例图及其邻接表: ``` graph = { 'A': {'B': 1, 'C': 4}, 'B': {'A': 1, 'C': 2, 'D': 5}, 'C': {'A': 4, 'B': 2, 'D': 1}, 'D': {'B': 5, 'C': 1} } ``` 使用Dijkstra算法求解起点`A`到其它节点的最短路径: ```python distances = dijkstra(graph, 'A') print(distances) ``` 输出结果为: ``` {'A': 0, 'B': 1, 'C': 3, 'D': 4} ``` 表示起点`A`到各个节点的最短距离。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值