单源最短路
Dijkstra(不存在负权边)
基本思路:
初始化:dist[i]表示第i个数到起点的距离,因此初始化dist[1] = 0 ,其他dist初始化为无穷(方便求最小值)
遍历所有点,将集合外dist最小的点添加入集合中(集合是已经确认是最短路径集合)
然后用该点更新其他点的dist
-
最短路1:
https://www.acwing.com/activity/content/problem/content/918/ -
最短路2:(Dijkstra的堆优化)
思路: 对寻找集合外dist最小的点进行堆优化
维护一个堆,从堆顶提取出最小值(小根堆),若该点不在集合中,则用该点更新它所连接的点,将更新的点加入堆中
https://www.acwing.com/activity/content/problem/content/919/
<< 优先队列 >>
* 升序队列
`priority_queue <int,vector<int>,greater<int> > q;`
* 降序队列
`priority_queue <int,vector<int>,less<int> >q;`
bellman-ford
特征:存在负权边
基本思路:
初始化:dist[i]表示第i个数到起点的距离,因此初始化dist[1] = 0 ,其他dist初始化为无穷(方便求最小值)
在限制边数中 遍历所有边,对终点(有向图)的dist进行更新 // 由于对边进行遍历可以采用结构体存储
注意!! 要在对边的遍历前进行备份,避免用当前循环更新后的新边dist更新当前为更新的边导致串联
最后的判断中,由于存在有限跳负权边,因此不能到达的dist未必等于0x3f3f3f3f,因此可以用其一半进行判断
- 最短路:有边数限制的带负权边的最短路(只能用bellman-ford算法)
https://www.acwing.com/activity/content/problem/content/922/
spfa (要求图中不含有负环)
特征:存在负权边
基本思路:
spfa算法也可以代替dijkstra算法解决正权边问题,而其本身也类似堆优化后的dijkstra算法
思路:从bellman_ford算法出发,在对终点的dist进行更新时,只有当起点变小终点才会可能发生变化
因此spfa算法优化该过程,用维护一个队列,只要有点的dist变小就放入队列
每次循环将队列中的数拿出来对其终点进行更新,若产生更新就将更新点加入队列
-
最短路:
https://www.acwing.com/activity/content/problem/content/920/ -
判断是否有负环
https://www.acwing.com/activity/content/problem/content/921/