Dijkstra演算法的實現及原理
阿新 • • 發佈:2019-01-10
演算法用處與基本思想
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;
}