基于Dijstra算法的删除路径后的最短问题| 豆包MarsCode AI刷题

127 阅读3分钟

题目分析

除了起点与终点以外,所有点之间有连接,连接的权重是欧几里得距离,典型的图结构中的最短路径问题。因自然而然的想到最短路径问题适合使用 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算法算是求解最短路径问题经典算法,通过多刷题可以了解到这个算法并不复杂,但是应用很多。