bellman_ford之单源有限最短路

一、题目描述

 二、解题思路

三、完整代码

 四、总结


往期博文:

bellman_ford之判断负权回路-优快云博客

Bellman_ford 算法--带负权值的单源最短路问题,边列表存储-优快云博客

这三道题目都是关于bellman_ford求最短路的问题,只是条件不同,这是最后一期,建议大家三期一期学习哦👍👍👍

一、题目描述

  

 二、解题思路

         最多经过 k 个城市的条件下,而不是一定经过k个城市,也可以经过的城市数量比k小,但要最短的路径

在 kama94.城市间货物运输I 中我们讲了:对所有边松弛一次,相当于计算 起点到达 与起点一条边相连的节点 的最短距离。节点数量为n,起点到终点,最多是 n-1 条边相连。 那么对所有边松弛 n-1 次 就一定能得到 起点到达 终点的最短距离。

本题是最多经过 k 个城市, 那么是 k + 1条边相连的节点。 所以本题就是求:起点最多经过k + 1 条边到达终点的最短距离。

所有边松弛一次,相当于计算 起点到达 与起点一条边相连的节点 的最短距离,那么对所有边松弛 k + 1次,就是求 起点到达 与起点k + 1条边相连的节点的 最短距离。

        但是这样就造成了一个情况,即:计算minDist数组的时候,基于了本次松弛的 minDist数值,而不是上一次 松弛时候minDist的数值。所以在每次计算 minDist 时候,要基于 对所有边上一次松弛的 minDist 数值才行,所以我们要记录上一次松弛的minDist。😢😢😢😢😢

why?

在对所有边松弛第一次的过程中,大家会发现,不仅仅 与起点一条边相连的节点更新了,所有节点都更新了。

而且对所有边的后面几次松弛,同样是更新了所有的节点,说明 至多经过k 个节点 这个限制 根本没有限制住,每个节点的数值都被更新了。 代码随想录 ---可以看看卡哥是怎么讲解的呜呜呜

三、完整代码

//对所有边松弛k+1次
#include<bits/stdc++.h>
using namespace std;

int main()
{
    int n,m;
    cin>>n>>m;
    vector<vector<int>> edges;
    for(int i=1;i<=m;i++)
    {
        int s,t,v;
        cin>>s>>t>>v;
        edges.push_back({s,t,v});
    }
    int src,dst,k;
    cin>>src>>dst>>k;
    int start=src;
    int end=dst;
    //初始化距离数组
    vector<int> mindist(n+1,INT_MAX);
    // 用来记录上一次遍历的结果
    vector<int> mindist_copy(n + 1); 
    mindist[start]=0;
    //对每条边进行k+1次松弛
    for(int i=1;i<=k+1;i++)
    {
        mindist_copy = mindist; // 获取上一次计算的结果
        for(auto edge:edges)
        {
            int from=edge[0];
            int to=edge[1];
            int cost=edge[2];
            // 注意使用 minDist_copy 来计算更新 新的minDist[to] 
            if(mindist_copy[from]!=INT_MAX)
            {
                mindist[to]=min(mindist[to],mindist_copy[from]+cost);
            }

        }
    }
    if(mindist[end]==INT_MAX) cout<<"unreachable";
    else cout<<mindist[end];
    return 0;
}

 四、总结

        auv,现在我刚学玩这个系列,真的感觉很熟悉很熟悉了,代码写了五六七八遍了,但是我相信自己下次碰到类似的新题,,,,,肯定不能一鼓作气写出来代码。。。。Bellman-Ford的核心优势是能够处理图中存在负权边的情况,但是即使图中所有边权均为非负值,Bellman-Ford算法仍然能正确计算最短路径,只是效率不如Dijkstra算法【看下面的博客,说实话我已经忘了他是怎么更新 的了.......😭😭​​​​​​​😭​​​​​​​😭

算法-图-dijkstra 最短路径-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值