青岛oj集训4

Dijkstra算法——单源最短路

  1. 算法流程(O(m+n^2))

1)把dis[1(起点)]=0,dis[……]=inf

2)从一号点向每条出边做松弛,更新dis,把1打标记

3)从未被打标记的点中选出dis最小的点,向所有临边(未被打标记)做松弛,更新dis(共执行n轮)

(性质:当一个点被打上标记时,最终最短路已经被完全确定)

(证明:因为这个点必须要是当时dis最小的点,那么任何其他点的dis+正边权就要大于这个点的dis)

(所以dijk只能在正权图里跑)

 2.优化(O(m log m))->如果遇到稠密图,m变成n^2级别,会比不优化还慢

每一轮都要暴力枚举每个点以找到最小的点,太暴力

所以要快速维护出未被标记且dis最小的点

所以要使用优先队列

使用大根堆倒着存(小根堆也行)

由于代码用的是vector存图,然后还要存点和边权

所以vector开的是一个node(struct)类型

但是无论大根堆还是小根堆都要用到小于号

小于号没法比较你自己定义的struct的

所以要对小于号进行重定义,即让它变成比较两个node相比较

所以要在struct里面进行重定义

看下面的代码,可以翻译成中文:

如果一个node小于另一个名为a的node(你要是写成名为a的int也行,不过这题要用大根堆,小于号比较的两端都是node),代表的含义是:

这个node的len参数要大于a的len参数。

为啥是大于呢?

首先这里是大根堆反着用

大根堆会把优先级高的数放在前面

大根堆有个反常性质:如果一个数小于另一个数,那么它会认为后边的优先级更高(更小)

所以一个node小于另一个名为a的node,就是一个node优先级低于a

他以为a更大,因为a的优先级更高

所以他会把a往上放

我们不这样想啊,我们想把len小的往上放

所以当a往上放时,我们希望a.len更小

所以代表的含义是:

这个node的len参数要大于a的len参数。

3.次短路与k短路

记录dis[i][j],表示i点的第j+1短的路径

更新到一个新的路径值

posted @ 2025-04-29 21:11  永韶  阅读(16)  评论(0)    收藏  举报