最短路之dijkstra演算法

2021-08-20 13:30:43 字數 3732 閱讀 1188

dijkstra演算法

1.定義概覽

dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算乙個節點到其他所有

節點的最短路徑。主要特點是

以起始點為中

心向外層層擴充套件,直到擴充套件到終點為止。

問題描述:在無向圖 g=(v,e) 中,假設每條邊 e[i] 的長度為 w[i],找到由頂點 v0 到其

餘各點的最短路徑。(單源最

短路徑)

2.演算法描述

1)演算法思想:設g=(v,e)是乙個帶權有向圖,把圖中頂點集合v分成兩組,第一組為已

求出最短路徑的頂點集合(用

s表示,初始時

s中只有乙個源點,以後每求得一條最短路徑 , 就將加入到集合s中,直到全部頂點都

加入到s中,算

法就結束了),第二組為其餘

未確定最短路徑的頂點集合(用u表示),按最短路徑長度的遞增次序依次把第二組

的頂點加入s中。在加入的過程中,總保持從

源點v到s中各頂點的最短路徑長度不大於從源點v到u中任何頂點的最

短路徑長度。此

外,每個頂點對應乙個距離,s中的頂點的

距離就是從v到此頂點的最短路徑長度,u中的頂點的距

離,是從v到此頂點只包括s中

的頂點為中間頂點的當前最短路徑長度。

2)演算法步驟:

a.初始時,s只包含源點,即s=,v的距離為0。u包含除v外的其他頂點,即:u=,若v與u中頂點u有

邊,則正常有權值,若u不是v的出邊鄰接點,則

權值為∞。

b.從u中選取乙個距離v最小的頂點k,把k,加入s中(該選定的距離就是v到k的最短

路徑長度)。

c.以k為新考慮的中間點,修改u中各頂點的距離;若從源點v到頂點u的距離(經過頂

點k)比原來距離(不經過頂

點k)短,則修改頂點u的距離值,修改後的距離值的頂點

k的距離加上邊上的權。

d.重複步驟b和c直到所有頂點都包含在s中。

執行動畫過程如下圖

**太快可以看下面的例子:

重點需要理解這句拗口的「

按最短路徑長度的遞增次序依次把第二組的頂點加入

s

中。

在加入的過程中,總保持從源

v

s

中各頂點的最短路徑長度不大於從源點

v

u

中任

何頂點的最短路徑長度

實際上,

dijkstra

演算法是乙個排序

過程

,就上面的例子來說,是根據

a到圖中其餘點的

最短路徑長度進行排序,路

徑越短越先被找到,路徑越長越靠後才能被找到,要找a到

f的最短路徑,我們依次找到了 :

a –> c 

的最短路徑 

3 a –> c –> b 

a –> c –> b 

a –> c –> b 

的最短路徑 

5 a –> c –> d 

a –> c –> d 

a –> c –> d 

的最短路徑 

6 a –> c –> e 

a –> c –> e 

的最短路徑 

7a –> c –> d –> f 

a –> c –> d –> f 

的最短路徑 

9 a –> c 

的最短路徑 

3 a –> c –> b 

的最短路徑 

5 a –> c –> d 

a –> c –> d 

的最短路徑 

6 a –> c –> e 

的最短路徑 

7 a –> c –> d –> f 

a –> c –> d –> f 

的最短路徑 

9 為什麼

dijkstra 

演算法不適用於帶負權的圖? 

就上個例子來說,當把乙個點選入集合

s時,就意味著已經找到了從

a到這個點的最短

路徑,比如第二步,把c點選

入集合s

,這時已經找到a到

c的最短路徑了,但是如果圖

中存在負權邊,就不能再這樣說了。舉個例子,假設有乙個點z

,z只與a

和c有連線,從a

到z的權為50,從z

到c的權為-49

,現在a到c

的最短路徑顯然是

a –> z –> c

再舉個例子:

在這個圖中,求從a到c的最短路,如果用dijkstra根據貪心的思想,選擇與a最接近的

點c,長度為7,以後不再變

化。但是很明顯此圖最短路為5。歸結原因是dijkstra採用

貪心思想,不從整體考慮結果,只從當前情況考慮選擇最

優。4.**模板

#include#include

#define inf 0x3f3f3f3f

int map[110][110],dis[110],visit[110

];/*

關於三個陣列:map陣列存的為點邊的資訊,比如map[1][2]=3,表示1號點和2號點的距離為3

dis陣列存的為起始點與每個點的最短距離,比如dis[3]=5,表示起始點與3號點最短距離為5

visit陣列存的為0或者1,1表示已經走過這個點。

*/int

n,m;

intdijstra()

visit[

1]=1

; dis[

1]=0

;

for(i=1; i)

}visit[pos]=1;//

表示這個點已經走過

for(j=1; j<=n; ++j)

}return

dis[n];

}int

main()

}inta,b,c;

for(i=1; i<=m; ++i)

int count=dijstra();

printf(

"%d\n

",count);

}return0;

}

最短路演算法之 Dijkstra演算法

dijkstra演算法 dijkstra演算法是典型最短路演算法,用於計算乙個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。dijkstra演算法能得出最短路徑的最優解,但由於它遍歷計算的節點很多,所以效率低。dijkstra演算法是用來求任意兩個頂...

最短路徑 之Dijkstra演算法

dijkstra演算法dijkstra 鄰接矩陣 int n,e maxv maxv int dis maxv pre maxv pre用來標註當前結點的前乙個結點 bool vis maxv void dijkstra int s if u 1 return visit u true for in...

最短路徑 之Dijkstra演算法

dijkstra演算法 dijkstra 鄰接矩陣 int n,e maxv maxv int dis maxv pre maxv pre用來標註當前結點的前乙個結點 bool vis maxv void dijkstra int s if u 1 return visit u true for i...