學習筆記·堆優化$\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

相關文章
相關標籤/搜索