迪捷斯德拉算法 (借助小根堆)
堆的简单使用可参考,我的博客https://blog.csdn.net/qq_46258829/article/details/134386437?spm=1001.2014.3001.5501
1.构建邻接表(邻接矩阵也可)
形如 本节点到自身距离可自行设定 (各人习惯,下面将演示先全设为inf 然后将自身再设为0)
# 初始化 (自己到自己设为 inf(无限)
[inf, inf, inf, inf, inf]
[inf, inf, inf, inf, inf]
[inf, inf, inf, inf, inf]
[inf, inf, inf, inf, inf]
[inf, inf, inf, inf, inf]
# 初始化 (自己到自己设为0)
[0, inf, inf, inf, inf]
[inf, 0, inf, inf, inf]
[inf, inf, 0, inf, inf]
[inf, inf, inf, 0, inf]
[inf, inf, inf, inf, 0]
邻接表结构体初始化
# 邻接表 初始化
adjgraph = [[float('inf')] *(n) for _ in range(n)]
for i,j,val in edges:
adjgraph[i][j] = val
adjgraph[j][i] = val
res = [float('inf'),0]
2.算法主体
首先初始化起点到所有点的距离 dist,默认为 inf,然后定义自己到自己距离为 0.
将 节点 和 到原点的距离信息,存成 list 格式:[节点,到原点距离],然后类似bfs,将它存入大list。
从大list中,pop 出 当前节点curr 和 当前节点到原点距离distance。
然后开始探索邻居。
先比较 结果dist 和 distance 的关系,若前<后,直接跳过。
if dis[curr] < distance:
continue
然后再比较(source->next_node 的距离)和(source-> curr + curr -> next_node 的距离).如果大于,那么更新
if adjgraph[curr][next_node] != float('inf') and dis[next_node] > distance + adjgraph[curr][next_node]:
dis[next_node] = dis[curr]+ adjgraph[curr][next_node]
heapq.heappush(q,[dis[next_node],next_node])
完整代码
# 邻接表
adjgraph = [[float('inf')] *(n) for _ in range(n)]
for i,j,val in edges:
adjgraph[i][j] = val
adjgraph[j][i] = val
res = [float('inf'),0]
for s in range(n):
# 存储从 s 出发,到各个节点的位置
dis = [float('inf') for _ in range(n)]
# 自身距离设为0 如果想设为 inf 可不加这行
# dis[s] = 0
# 借助堆实现
q = []
heapq.heappush(q,[0,s]) # 小根堆
while q:
# 从 q 中提取 curr 到原点距离,以及当前 curr 节点
distance,curr = heapq.heappop(q)
# 如果存储的已经是最小的,无需更新,跳过即可
if dis[curr] < distance:
continue
for next_node in range(n):
# curr 到 next_node 的距离是存在的,不是无穷的
# s 到 next_node 的距离,如果大于 curr 的距离 + curr 到 next_node 的距离。
if adjgraph[curr][next_node] != float('inf') and \
dis[next_node] > distance + adjgraph[curr][next_node]:
# 更新
dis[next_node] = dis[curr]+ adjgraph[curr][next_node]
heapq.heappush(q,[dis[next_node],next_node])
# 显示将结果
print(s,dis)
1334.阈值距离内邻居最少城市
有 n
个城市,按从 0
到 n-1
编号。给你一个边数组 edges
,其中 edges[i] = [fromi, toi, weighti]
代表 fromi
和 toi
两个城市之间的双向加权边,距离阈值是一个整数 distanceThreshold
。
返回能通过某些路径到达其他城市数目最少、且路径距离 最大 为 distanceThreshold
的城市。如果有多个这样的城市,则返回编号最大的城市。
注意,连接城市 i 和 j 的路径的距离等于沿该路径的所有边的权重之和。
题解:循环所有节点,把每一个都当成起点,然后应用 迪杰斯特拉算法,然年选出距离最小的即结果
class Solution:
def findTheCity(self, n, edges, distanceThreshold):
# 邻接表
adjgraph = [[float('inf')] *(n) for _ in range(n)]
for i,j,val in edges:
adjgraph[i][j] = val
adjgraph[j][i] = val
res = [float('inf'),0]
for s in range(n):
dis = [float('inf') for _ in range(n)]
dis[s] = 0
q = []
heapq.heappush(q,[0,s])
while q:
distance,curr = heapq.heappop(q)
if dis[curr] < distance:
continue
for next_node in range(n):
if adjgraph[curr][next_node] != float('inf') and \
dis[next_node] > distance + adjgraph[curr][next_node]:
dis[next_node] = dis[curr]+ adjgraph[curr][next_node]
heapq.heappush(q,[dis[next_node],next_node])
cont = 0
for i in range(n):
if dis[i] <= distanceThreshold:
cont+= 1
if cont <= res[0]:
res[0] = cont
res[1] = s
return res[1]