ACM 演算法 堆優化Dijkstra演算法

2021-09-25 17:17:53 字數 2468 閱讀 3433

對於乙個邊權為正的圖,我們可以利用dijkstra演算法求出單源最短路徑(sssp),對於常規的dijkstra演算法,其複雜度為 o(n

2)

o(n^2)

o(n2

) ,顯然在 n

nn 較大的時候,可能導致耗時過長,通過優化我們可以獲得一種更加快速的dijkstra演算法,時間複雜度為 o(m

logn

)o(mlogn)

o(mlog

n)。在傳統的dijkstra演算法中,在d[n]中尋找未被訪問且最小的d[i]採用的是遍歷陣列的方式,這樣會導致時間的複雜度變高,既然是輸出最小的權值邊,那麼我們可以用stl中的priority_queue的優先佇列來實現這一操作,可以實現加速。當然,為了實現這一操作,我們儲存圖也不再利用簡單的鄰接矩陣,而是先儲存邊的資料,再將邊的資料儲存到vector陣列中,有點像鄰接表,但不是鄰接表。

**源於《演算法競賽入門經典(第2版)》(紫書)

struct edge};

struct heapnode};

struct dijkstra

void

addedge

(int from

, int to, int dist)

void

dijkstra

(int s));

while(!

q.empty()

));}

}}}}

;

看了上述的**,不妨來做道題試試。

題目:j-free:

題意:給定乙個圖,有 n

nn 個點, m

mm 個邊,每個邊的權值為 l

ll, 你可以讓圖上至多 k

kk 個邊的權值變為 0

00,請問,在這樣的操作過後,從頂點 s

ss 到頂點 t

tt 的最短路徑是多少。

題解:在了解了上述的關於堆優化的dijkstra演算法過後,對於解這題很有幫助。由於到點的距離與 k

kk 有了關係,我們不能再用原先的一維陣列d[n]來儲存到各個點的距離的最短路徑,而是要開乙個二維陣列dis[n][m],其中dis[i][j]表示從源點到頂點 i

ii 在使 j

jj 個邊的權值變成 0

00 的情況下的最短路徑。這樣我們就很容易地可以獲得答案了。那麼要如何建立這個二維陣列dis[n][m]呢,在原先的dijkrstra演算法中,我們向q中push乙個heapnode的條件是d[e.to] > d[u] + e.dist,在這裡由於多了乙個考慮因素 k

kk ,所以我們的heapnode中要增加乙個變數ktime來表示刪掉權值邊的個數。同時,push的判定條件,也由原來的乙個變成了兩個,乙個是在ktime不變的情況下是否push,另乙個是在ktime+1的情況下是否push。這樣就可以完美地構建出二維陣列的dis[n][m]了。最後在尋找 ans

ansan

s 時,只需要遍歷dis[t]即可。

**

#include .h>

using namespace std;

const int maxn =

1e3+5;

typedef long long ll;

#define inf

1e9+

5int n, m,s,

t, k;

ll dis[maxn]

[maxn]

;struct edge};

struct heapnode};

struct dijkstra

void

addedge

(int from

, int to, int dist)

void

dijkstra

(int s));

while(!

q.empty()

));}

if(ktime[ktime]

[ktime+1]

));}

}}}}

;int main()

dij.

dijkstra(s

);ll ans =

inf;

for(int i =

0; i <= k; i++

)printf

("%lld"

, ans)

;return0;

}

dij演算法堆優化 Floyd演算法

乙個號稱只有5行 的演算法,由1978年圖靈獎獲得者 史丹福大學電腦科學系教授羅伯特 弗洛伊德命名。該演算法有於求乙個帶權有向圖 wighted directed graph 的任意兩點的最短距離的演算法,運用了動態規劃的思想,演算法的時間複雜度為o v 3 空間複雜度o v 2 其核心思想是,在兩...

ACM特定演算法的卡常優化

今天做一道樹鏈剖分的題目,發現被卡常了,於是修改了很久,列印出執行時間,發現有這3個地方對常數的影響特比大 1.i o 用輸入外掛程式所消耗的時間大概是用關同步 tie的cin的一半 測試 輸入了1e5 3的資料,cin用了0.2s,in用了0.1s 2.vector 鏈式前向星 不得不說cache...

廣度優先演算法,深度優先演算法和DijKstra演算法

我們經常會碰到最短路徑問題,而最短路徑問題的解決方法多種多樣,廣度優先搜尋 bfs 深度優先搜尋 dfs 和dijkstra演算法貌似都能解決這個問題,這裡就簡單介紹一下這些演算法,分析一下它們的適用範圍。一 原理剖析 1 廣度優先搜尋 bfs 廣度優先搜尋依賴的是佇列解決問題。佇列中的每乙個節點需...