1. 程式人生 > 其它 >堆優化版dijkstra

堆優化版dijkstra

堆優化版dijkstra

一:使用範圍

  單源最短路,所有邊權都是正數,稀疏圖(邊數和點數相差不大),時間複雜度(mlogn);

二:優化思路

  樸素版dijkstra 遍歷所有點比較找出距離最近的點使用優先佇列進行優化;

  稀疏圖用鄰接表存圖;

  1.將優先佇列定義成小根堆priority_queue<PII,vector<PII>,greater<PII>> heap;

  2.源點距離初始化為0,插入優先佇列,從該點開始擴充套件;heap.push({0,1});

  3.隊頭元素t儲存到一個臨時變數ver中,並將隊頭元素出隊;

  4.更新該點的到源點的最短距離

  由於有重邊的原因,可能有冗餘項。由於是小根堆,最短的距離會先出隊,再進行標記,下次遇到已標記的continue;

程式碼附上。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<queue>
 4 using namespace std;
 5 typedef pair<int,int>PII;
 6 const int N=150010;
 7 int h[N],e[N],w[N],nex[N],idx;
 8 int dist[N];
 9 bool str[N];
10 int n,m;
11 void add(int a,int b,int c) 12 { 13 e[idx]=b;w[idx]=c;nex[idx]=h[a];h[a]=idx++; 14 } 15 int dijkstra() 16 { 17 memset(dist,0x3f,sizeof dist); 18 dist[0]=1; 19 priority_queue<PII,vector<PII>,greater<PII>> heap; 20 heap.push({0,1}); 21 while(heap.size()) 22 {
23 auto t=heap.top(); 24 heap.pop(); 25 int ver=t.second,distance=t.first; 26 if(str[ver]) continue; 27 str[ver]=true; 28 for(int i=h[ver];i!=-1;i=nex[i]) 29 { 30 int j=e[i]; 31 if(dist[j]>distance+w[i]) 32 { 33 dist[j]=distance+w[i]; 34 heap.push({dist[j],j}); 35 } 36 } 37 } 38 if(dist[n]==0x3f3f3f3f) return -1; 39 return dist[n]; 40 } 41 int main() 42 { 43 cin>>n>>m; 44 memset(h,-1,sizeof h); 45 while(m--) 46 { 47 int x,y,z; 48 cin>>x>>y>>z; 49 add(x,y,z); 50 } 51 int k=dijkstra(); 52 cout<<k<<endl; 53 return 0; 54 }
View Code