学习笔记·堆优化$\mathscr{dijkstra}$

嘤嘤嘤今天被迫学了这个算法……其实对于学习图论来讲我心里是拒绝的$\mathscr{qnq}$node

因为发现关于这个$\mathscr{SPFA}$的时间复杂度$O(kE)$中的$k \approx 2$好像只针对于稀疏图?$emmm$想不到时间复杂度竟然还有数据分治这一说$ORZ$算法

好的,对于个人图论而言,好像只会$MST$、$\mathscr{MT \ \ Law}$和最短路?哦呵呵呵呵那可真优秀啊$QAQ$app

要不是今天上午学了堆优化的,没准我连普通的都不会了!学习


回归正题,最朴素的$\mathscr{dijkstra}$的思想是咱们要从已知的点里面选一个离源点最近的,而后以此不断松弛周围的点(代码显性),并保存这个点的最短路(代码隐性)。而$dijkstra$遵循的是贪心思想,就是在边权都是正的的状况下,当前找到的最短路必定是对于这个点全局最优,由于不会再有更短的路径了——而显然这个贪心在有负权边的时候的错误的。优化

因而咱们发现,对于其中“找到最近的点”,即当前记录的$dist_i$最小的$i$,是有优化性可言的。朴素是$O(n)$的查询,加上堆以后就能够变成$O(logn)$。因此本来时间复杂度$O(mn)$的$dijkstra$就能够优化成$O(mlogn)$,而且相对稳定。code

因而核心的代码就是这一部分啦~class

inline void dijistra(){
    fill(dist + 1, dist + N + 1, 2147483647) ; 
    q.push((node){S, 0}) ; dist[S] = 0 ;
    while(!q.empty()){
        node qwq = q.top() ; q.pop() ;
        x1 = qwq.t, x2 = qwq.v ;
        if(vis[x1]) continue ; vis[x1] = 1 ;
        for(k = head[x1]; k ; k = e[k].next){
            dist[e[k].to] = min(dist[e[k].to], x2 + e[k].v) ;
            q.push((node){e[k].to, dist[e[k].to]}) ;
        }
    }

$qwq$就这样了next

相关文章
相关标签/搜索