【最短路】Djikstra算法

作为一名蓝桥杯er(今年acm成绩并不理想),还有一个星期,蓝桥杯国赛就要到来,我肯定是希望能够拿到国赛一等奖的,也有可能事与愿违;

总之现在来讲一下常用的Djikstra算法,效率高但是不支持负权,而之前写的bellmanford能够支持负权环,至于能够支持负权环的floyd算法,可能得下次再学;

至于存图结构,我想了一下,邻接表和链式前向星可能差不多,而邻接矩阵太慢,具体可以看这篇文章链式前向星,也可以看我的前一篇文章,总之,链式前向星我认为是一个很好用,很好理解并且很好写的数据结构。

对于最短路算法,我觉得bellmanford算法很像dfs,而Djikstra像bfs,可以看我之前写的DFS和BFS,一个是一直遍历到最内层(尽管“松弛”操作使得循环并不是一次进行到底),另一个则是将每一层单独放进一个队列并且进行遍历,结构上都非常相似(以上是笔者的一些理解,可能有些人学的板子和我的不一样,不要见怪),而且笔者不会制作动图和动态视频,这个资源在网上随便能找到,如果对文字说明还是不能理解的话就去找个视频看看。

存图在这里也不过多赘述,这里直接上代码

vector<ll>dist(n+1,INT_MAX);//1到每个点的距离,初始为无限远
    vector<bool>vis(n+1,false);//走过的就不再走,避免重复操作
    dist[1]=0;
    priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>>pq;
    //first是当前的距离,second是当前的节点
    pq.push({dist[1],1});//放入第一个元素,进入循环
    while(pq.size())
    {
        ll crrDist=pq.top().first;//这句可以不要,为了规范理解所以保留
        ll u=pq.top().second;//本次的起点
        pq.pop();
        if(vis[u])continue;//如果走过就跳过
        vis[u]=true;//标记
        for(ll i=head[u];i!=-1;i=edge[i].next)//循环这个节点的每一个子节点
        {
            dist[edge[i].goal]=min(dist[edge[i].goal],dist[u]+edge[i].value);//松弛
            pq.push({dist[edge[i].goal],edge[i].goal});//推入下一个节点
        }
    }

可见vis数组,以及队列(此处因为要找最短路所以使用小根堆,也可以全部存进队列然后再遍历比较大小,尽管这个操作显得多余且时效性不如优先队列)和BFS的代码如出一辙,只是稍加修改,能够理解代码就说明学会了(

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值