蓝桥杯复习之Dijkstra算法(过程+理解+超级好懂!!!)

步骤

  1. 初始化邻接矩阵 dist 和答案数组 d(记录边权 : dist[i][j] = a ,从i --> j 权值为a), d[i] 表示min distance[ 1 --> i ] .(我习惯用dist数组直接进行初始化d数组)
    在这里插入图片描述
  2. 每一次先从所以节点中去寻找最小的d [ t ] ,(第一次是找到由1个节点组成的最短路径长度,第i次是找到由i个节点组成的最短路径的长度…)
  3. 然后以当前找到的t节点为末尾,对每个节点j进行和t 更新到t的距离(不用管前i-1个点
    可能很多小伙伴回问了: 为什么不用管前i-1个?

在这里插入图片描述
如上图:我们假如现在i为3。我们可以看见其是(1 - 2 - 4 - 5)的路径长度是要更加小的,但是我们最终是要得到n个节点的路径,全局的情况下肯定是在前i个最短的路径上再加是argmin(dist [ i , j ]) 或者直接是dist[ 1 , j ]为答案。

来一个题目试试(附有代码

题目:

给定一个 n n n 个点 m m m 条边的有向图,图中可能存在重边和自环,所有边权均为正值。

请你求出 1 1 1 号点到 n n n 号点的最短距离,如果无法从 1 1 1 号点走到 n n n 号点,则输出 − 1 -1 1

输入格式

第一行包含整数 n n n m m m

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

输出格式

输出一个整数,表示 1 1 1 号点到 n n n 号点的最短距离。

如果路径不存在,则输出 − 1 -1 1

数据范围

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

输入样例:
3 3
1 2 2
2 3 1
1 3 4
输出样例:
3
n , m =map(int,input().split())
dist = [[float('inf') for i in range(n+1)] for j in range(n+1)]

for i in range(m):
    a,b,distance = map(int,input().split())
    if a == b :continue
    dist[a][b] = min(dist[a][b],distance)

d = [dist[1][i] for i  in range(n+1)]
state = [True for i  in range(n+1)]

d[1] =0
state[1] = False
for i in range(2,n+1):
    t = -1
    for j in range(1,n+1):
        if state[j] and (t==-1 or d[t]>d[j]):  t = j
#dijkstra每次找到由i个节点组成的最短路径,并以当前找到的t节点为末尾,
#对每个节点j进行和t  更新到t的距离(不用管前i-1个点)
    for j in range(1,n+1):
        d[j] = min(d[j] , d[t] + dist[t][j])
    state[t] = False


if d[n] == float('inf'):print(-1)
else:print(d[n])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值