C++图论基础单源最短路四种算法总结

本篇来自小编手搓~


常规版 - dijkstra堆优化 - dijkstrabellman-ford 算法spfa 算法
算法思想

基于贪心策略:

        每次拿出还未确定最短路的点中,距离起点最近的点;

        打上标记;

        打上标记之后,跟新刚刚打上标记的点的出边连接的点的最短路。

---真实的情况只需要执行 n - 1 次,最后没有出边的点实际不需要再执行单趟操作,但是,如果在跑算法的过程中,跟新累加结果,只单单执行 n - 1 次是不够的,所以,我们为了保险,均执行 n 次~

使用堆优化找点操作:

        把还没有确定最短路的点扔进堆中,方便找距离起点最近的点。

暴力松弛:

        执行 n - 1 轮松弛操作;

        单趟扫描所有的边看看能不能松弛。

---bool 类型的 flag 还可以进行一定的优化,因为并不是每个图都必须跑满 n - 1 轮松弛操作才能找到最短路。

使用队列优化bellman-ford 算法:

        只有上一轮被松弛的点,下一轮才有可能引起松弛操作。

---队列就是维护这些实际可以引起松弛操作的点;spfa 算法中的 st 数组是标记哪些点在队列中;队列维护的点不能有重复--该点在从队列中拿出时,是可以拿到最新值的。

负边权

失效

        出现负边权时贪心策略不正确

失效可行可行
负环失效失效

可以判断负环:

        存在负环,BF算法就可以超出 n - 1 轮的限制,执行超过 n - 1 轮松弛操作;

        执行 n 轮,判断是否有松弛操作。

可以判断负环:

        存在负环,while 循环会死循环;

        创建 cnt 数组,给每个节点都配上一个“记边器”,标记从起点到该点的边数,每跟新一个节点,实时判断是大于 n - 1 条边存在负环,还是小于等于 n - 1 存在最短路,不存在负环。

时间复杂度O(n^2)O(m log m)O(nm)O(km) ~ O(nm)

此外,其实还有两个单源最短路算法,那就是普通 bfs 以及 01bfs:

普通 bfs 只能处理边权全部相同且非负的最短路;

01bfs 只能解决边权要么为 0,要么为 1 的情况。

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值