1. 程式人生 > >Dijkstra演算法(最短路徑)

Dijkstra演算法(最短路徑)

基本思想

每次找到離源點最近的一個頂點,然後以該頂點為中心進行擴充套件,最終得到源點到其餘所有點的最短路徑。

基本歩驟

  1. 將所有頂點分為兩部分:已知最短路徑的頂點集合P和未知最短路徑的頂點集合Q。最開始,已知最短路徑的頂點集合P中只有源點一個頂點。這裡用book陣列來記錄哪些點在集合P中。

  2. 設定源點S到自己的最短路徑為0 即dis[s]=0。若存在有源點能直接到達的頂點i,則dis[i] = e[s][i]。同時把所有其他源點不能直接到達的頂點的最短路徑設為∞。

  3. 在集合Q 中所有頂點中選擇一個離源點S最近的頂點U加入到集合P中。並考察所有以點U為起點的邊,對每一條邊進行鬆弛操作(以點U為中間點,計算最短路徑並更新集合Q)。

  4. 重複第三步,如果集合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演算法看程式碼有可能有點迷糊,但核心思想很十分簡潔,非常流弊啊!