前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【最短路算法】Dijkstra+heap和SPFA的区别

【最短路算法】Dijkstra+heap和SPFA的区别

作者头像
饶文津
发布2020-06-02 15:04:18
1.2K0
发布2020-06-02 15:04:18
举报
文章被收录于专栏:饶文津的专栏饶文津的专栏

单源最短路问题(SSSP)常用的算法有Dijkstra,Bellman-Ford,这两个算法进行优化,就有了Dijkstra+heap、SPFA(Shortest Path Faster Algorithm)算法。这两个算法写起来非常相似。下面就从他们的算法思路、写法和适用场景上进行对比分析。如果对最短路算法不太了解,可先看一下相关ppt:最短路

为了解释得简单点,以及让对比更加明显,我就省略了部分细节。

代码语言:javascript
复制
typedef pair<int,int> PII;
priority_queue<PII,vector<PII>,greater<PII> > q;
...
while(!q.empty()){  // O(V) 加上count<n可以优化一点点 
    int w=q.top().first, u=q.top().second;
    q.pop();   // O(lgV)
    if(b[u])continue; b[u]=true;
    //++count;
    for(int i=head[u];i;i=e[i].next){ // Sum -> O(E)
        int v=e[i].to;
        if(d[u]+e[i].w<d[v]){
            d[v]=d[u]+e[i].w;
            q.push(PII(d[v],v));  // O(lgV)
        }
    }
}

(O(kE))
(O(VE))

的SPFA

while(队非空)

-->队头出队,松弛它的边

-->松弛了且不在队内的点入队

代码语言:javascript
复制
while(!q.empty()){
    int u=q.front(); q.pop();
    b[u]=false;
    for(int i=head[u];i;i=e[i].next){
        int v=e[i].to;
        if(d[u]+e[i].w<d[v]){
            d[v]=d[u]+e[i].w;
            if(!b[v])b[v]=true,q.push(v);
        }
    }
}

算法思路对比

  • Dijkstra+heap是用小根堆,每次取出d最小的点,来更新距离,那么这个点来说,最小距离就是当前的d。
  • SPFA是用双端队列,每次取出队头,来更新距离,它之后可能还会入队。它是一种动态逼近法,因为每次松弛距离都会减小,所以松弛一定会有结束的。如果一个点入队超过n次就是存在负环。

复杂度分析对比

适用场景

如果是稠密图,Dijkstra+heap比SPFA快。稀疏图则SPFA更快。SPFA可以有SLF和LLL两种优化,SLF就是d比队头小就插入队头,否则插入队尾。

另外,Dijkstra和Prim也很相似,它们的区别主要是d的含义,前者是到s的临时最短距离,后者是到树的临时最短距离,相同点是,每次找d最小的更新其它点的距离。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-05-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 算法思路对比
  • 复杂度分析对比
  • 适用场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档