Dijkstrk算法朴素板

1. 问题描述:

给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为正值。请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 −1。

输入格式

第一行包含整数 n 和 m。
接下来 m 行每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。

输出格式

输出一个整数,表示 1 号点到 n 号点的最短距离。
如果路径不存在,则输出 −1。

数据范围

1 ≤ n ≤ 500,
1 ≤ m≤ 10 ^ 5,
图中涉及边长均不超过10000。

输入样例:

3 3
1 2 2
2 3 1
1 3 4

输出样例:

3

来源:https://www.acwing.com/problem/content/851/

2. 思路分析:

dijkstra算法求解单源最短路径问题(spfa算法也可以求解单源最短路径问题),也即求解从一个点到其余点的最短距离,dijkstra算法的思想其实也比较容易理解,首先我们需要找到dist数组或者列表中最短的边对应的点并且这个点之前是没有访问过的,然后从这个点出发,找到对应的出边,更新出边对应的dist位置,一直循环这个过程直到所有的顶点都已经被访问过了就停止了,此时dist数组或者列表存储的就是从源点到其余点的最短距离。因为使用的是python语言所以我们在建图的时候可以声明一个长度为n的列表dist,列表中的每一个元素为一个字典,这样dist就相当于是一个邻接表了。

3. 代码如下:

python:

from typing import List


class Solution:
    # k表示起点, n表示节点个数
    def dijkstra(self, nums: List[List[int]], n: int, k: int):
        # g中每一个元素都是一个字典, 这样相当于是一个邻接表, 下面这样声明比直接声明一个二维列表的耗时要短, python初始化一个长度比较大的列表的时候耗时很大
        g = [dict() for i in range(n + 1)]
        # 建图
        for x in nums:
            start, end, weight = x[0], x[1], x[2]
            # 这里有一个坑是一个点到另外一个点可能存在重复的边这个时候需要取最小的那条边
            if end in g[start]: g[start][end] = min(g[start][end], weight)
            else: g[start][end] = weight
        INF = 10 ** 10
        dist = [INF] * (n + 1)
        dist[k] = 0
        vis = [0] * (n + 1)
        for i in range(n):
            k = -1
            # _min表示当前最小值
            _min = INF
            # 使用循环找到当前距离最小的那个顶点
            for j in range(1, n + 1):
                if vis[j] == 0 and _min > dist[j]:
                    k = j
                    _min = dist[j]
            # 不存在没有更新的顶点就可以break了
            if k == -1: break
            vis[k] = 1
            for j in range(1, n + 1):
                # 由当前的点更新到其余点的最短距离
                if vis[j] == 0 and j in g[k] and dist[j] > dist[k] + g[k][j]:
                    dist[j] = dist[k] + g[k][j]
        return dist[n] if dist[n] != INF else -1


if __name__ == "__main__":
    # n表示节点数量, m表示边长
    n, m = map(int, input().split())
    nums = list()
    for i in range(m):
        start, end, weight = map(int, input().split())
        nums.append([start, end, weight])
    print(Solution().dijkstra(nums, n, 1))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值