1. 程式人生 > >Dijkstra演算法的實現及原理

Dijkstra演算法的實現及原理

演算法用處與基本思想

Dijkstra演算法的作用是求指定點到圖中任何一點的最短路徑。
其基本思路與BFS(深度優先搜尋)有些類似,但不同的是BFS用的是一般佇列,也就是嚴格的先進先出。而Dijkstra演算法用到的則是優先佇列。

什麼是優先佇列

優先佇列中是有序的佇列,其順序取決於規定的規則。比如可以規定值大的在前面,也可以規定值小的在前面。一般來說直接用STL裡面的priority_queue來實現,這個預設的是較大的值在前面。

演算法過程

有一個儲存到每個點最短路徑的陣列,這裡記為shortlen[](預設值為無窮,代表無通路)。還有一個記錄點是否被訪問過的陣列,這裡記為visit[]。
一開始,從起點開始,用每一個與起點相連的且沒有被訪問過的點的距離對shortlen陣列進行更新,例如:第i個點與起始點的距離為x,x小於無窮,那麼久把shortlen[i]的值更新為x。
只要有通路的點,全部放入優先佇列

然後把這個點記為被訪問過。
然後就從佇列裡取出隊頭,將其當做新的起點,重新進行上面的操作。
當佇列為空時跳出迴圈,這個時候的shortlen陣列的值就是起點到各個點的最短距離。

程式碼:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
using namespace std;
const int INF=65535;
const int maxn=110
; unsigned int mp[maxn][maxn]; bool visit[maxn]; unsigned int shortlen[maxn]; typedef struct Node{ int dis,v; bool operator < (const Node &cmp) const{//過載小於號,不理解的可以直接用。作用相當於定義一個優先佇列的比較規則 return dis > cmp.dis; } }Node; void Dijkstra(int start,int num) { int value; memset
(visit,false,sizeof(visit)); memset(shortlen,INF,sizeof(shortlen)); priority_queue<Node> q; shortlen[start]=0; q.push({0,start});//起點放入佇列 while(!q.empty()) { Node a=q.top();//取出 q.pop(); start=a.v; value=shortlen[start]; visit[start]=true;//記為訪問過 for(int i=1;i<=num;++i){ if(i==start) continue; if(mp[start][i]<INF&&visit[i]==false){ if(mp[start][i]+value<shortlen[i]) shortlen[i]=mp[start][i]+value;//更新陣列 q.push({shortlen[i],i}); } } } } int main() { // freopen("in.txt","r",stdin); int numv; int x,y,w,v; cout<<"InPut the number of v"<<endl; cin>>numv; memset(mp,INF,sizeof(mp)); cout<<"Build Map"<<endl; while(cin>>x>>y&&(x||y)) { cin>>w; mp[x][y]=w; mp[y][x]=w; } cout<<"Input the start"<<endl; cin>>v; Dijkstra(v,numv); for(int i=1;i<=numv;++i) cout<<"i="<<i<<" shortlen="<<shortlen[i]<<endl; cout<<endl; return 0; }