Dijkstra演算法(最短路徑)
阿新 • • 發佈:2019-02-18
基本思想
每次找到離源點最近的一個頂點,然後以該頂點為中心進行擴充套件,最終得到源點到其餘所有點的最短路徑。
基本歩驟
將所有頂點分為兩部分:已知最短路徑的頂點集合P和未知最短路徑的頂點集合Q。最開始,已知最短路徑的頂點集合P中只有源點一個頂點。這裡用book陣列來記錄哪些點在集合P中。
設定源點S到自己的最短路徑為0 即dis[s]=0。若存在有源點能直接到達的頂點i,則dis[i] = e[s][i]。同時把所有其他源點不能直接到達的頂點的最短路徑設為∞。
在集合Q 中所有頂點中選擇一個離源點S最近的頂點U加入到集合P中。並考察所有以點U為起點的邊,對每一條邊進行鬆弛操作(以點U為中間點,計算最短路徑並更新集合Q)。
重複第三步,如果集合Q為空,演算法結束。最終dis陣列中的值就是源點到所有頂點的最短路徑。
//C程式碼
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int main(){
int e[10][10],dis[10],book[10],i,j,n,m,t1,t2,t3,u,v,min;
int inf = 99999999;
scanf("%d %d",&n,&m);
//初始化
for(i=1 ;i<=n;i++){
for(j=1;j<=n;j++){
if(i==j) e[i][j]=0;
else e[i][j] = inf;
}
}
//讀入邊
for(i=1;i<=m;i++){
scanf("%d %d %d",&t1,&t2,&t3);
e[t1][t2]=t3;
}
//初始化dis陣列,這裡是1號頂點到達其餘各頂點的初始路程
for(i=1;i<=n;i++)
dis[i]=e[1][i];
for(i=1;i<=n;i++){
book[i]=0 ;
}
book[1]=1;
//Dijkstra演算法
for(i=1;i<=n-1;i++){
min = inf;
for(j=1;j<=n;j++){
if(book[j]==0 && dis[j]<min){
min = dis[j];
u=j;
}
}
//標記
book[u]=1;
//更新dis陣列
for(v=1;v<=n;v++){
if(e[u][v]<inf){//有路
if(dis[v]>dis[u]+e[u][v])//更短
dis[v]=dis[u]+e[u][v];
}
}
}
for(i=1;i<=n;i++)
printf("%d ",dis[i]);
return 0;
}
總結:迪傑斯特拉演算法給我的感覺就是走地圖,首先找出其中最短的路徑出發點,然後根據這個點跟新原有圖的資訊(找出的點本就是最短,所以更新的是未走的點),又得到最新所有地圖路徑,在找出其中最短出發點,,。依次遍歷,直到所有點被跟新完,最後最短路徑也就隨之出來了。有點貪心的感覺了=.=
Dijkstra演算法看程式碼有可能有點迷糊,但核心思想很十分簡潔,非常流弊啊!