题目分析
除了起点与终点以外,所有点之间有连接,连接的权重是欧几里得距离,典型的图结构中的最短路径问题。因自然而然的想到最短路径问题适合使用 Dijkstra 算法,我们将基于此算法来求解。
解题思路
1.欧几里得距离计算
首先,计算地图上任意两点之间的欧几里得距离。对于任意两个点i和j,其欧几里得距离可以通过公式:
distance(i,j)=sqaure[(x_i−x_j)^2+(y_i−y_j)^2]
来得到,其中(x_i, y_i)和(x_j, y_j)分别是点i和点j的坐标。
2.构建邻接矩阵
所有点之间的距离需要通过一个邻接矩阵来存储。邻接矩阵是一个二维数组,其中dist[i][j]表示点i和点j之间的距离。
3.Dijkstra算法
Dijkstra算法是一个贪心算法,适用于带权图的单源最短路径问题。我们使用最小堆(优先队列)来高效地获取当前最短路径的节点,并在每个步骤更新其他节点的最短路径。
4.避免删除的路径
由于s到t的直接路径被删除,我们在计算最短路径时需要确保不会走这条路径。具体做法是:在算法中跳过s到t或t到s的路径。
4.返回最终结果
最终,我们返回从起点s到终点t的最短路径,结果保留两位小数。
代码示例
import math
from heapq import heappush, heappop
def solution(n: int, s: int, t: int, x: list, y: list) -> str:
# 1.计算两点之间的欧几里得距离
def calculate_distance(x1, y1, x2, y2):
return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
# 2.构建距离矩阵,存储所有点对之间的距离
dist = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
if i != j:
dist[i][j] = calculate_distance(x[i], y[i], x[j], y[j])
# 3.使用Dijkstra算法查找最短路径
def dijkstra(start, end):
# 如果起点和终点是同一个,找最短的回环路径
if start == end:
min_cycle = float('inf')
for mid in range(n):
if mid != start-1:
cycle_dist = dist[start-1][mid] + dist[mid][start-1]
min_cycle = min(min_cycle, cycle_dist)
return min_cycle
# 初始化距离数组和访问节点集
distances = [float('inf')] * n
distances[start-1] = 0
pq = [(0, start-1)] # 优先队列
visited = set() # 访问过的节点
# 主循环,找最短路径
while pq:
d, curr = heappop(pq)
if curr in visited:
continue # 跳过已访问过的点
visited.add(curr)
if curr == end-1:
return d
# 遍历相邻节点
for next_node in range(n):
if next_node in visited or (curr == s-1 and next_node == t-1) or (curr == t-1 and next_node == s-1):
continue
new_dist = d + dist[curr][next_node]
# 更新最短路径
if new_dist < distances[next_node]:
distances[next_node] = new_dist
heappush(pq, (new_dist, next_node)) # 加入队列
return float('inf')
result = dijkstra(s, t)
return "{:.2f}".format(result)
总结
Dijkstra算法算是求解最短路径问题经典算法,通过多刷题可以了解到这个算法并不复杂,但是应用很多。