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

Dijkstra算法(最短路)

style 什麽 短路徑 cout def ios clas namespace end

Dijkstra算法是單源最短路徑算法;利用的是貪心思想,每次選擇當前的最靠近源點的頂點確定為最短路徑(所以Dijkstra算法需要滿足的是所有邊的權值都為正值,所以Dijkstra不能處理負邊權問題)。

算法思路:

1. 將所有點分為兩部分:已知最短路徑頂點和未知最短路徑頂點,先將源點加入已知最短路徑,利用book[]存儲。

2. 初始化各頂點的最短路徑,有源點直接相連的點設置為邊的權值,沒有直接相連的點設置為無窮大;

3. 在所有未知最短路徑的頂點中尋找距離最小的將其確定為最短路徑,並對這點的所有出邊進行松弛操作;

4. 重復3操作,直到所有點確定最短路徑;

代碼:

#include <string
.h> #include<iostream> #include<vector> #include<queue> #define _Max 200020 #define INF 1<<30 using namespace std; int main() { int e[10][10],dis[_Max],book[_Max]; int n,m,s,t,w; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i==j) e[i][j]=0
; else e[i][j]=INF; } } cin>>n>>m; for(int i=0;i<m;i++){ cin>>s>>t>>w; e[s][t]=w; } //初始化1號頂點到其他頂點的距離 for(int i=1;i<=n;i++){ dis[i]=e[1][i]; } //初始化book數組,1表示已求得最短路徑,0表示未知最短路徑 for(int i=1;i<=n;i++){ book[i]
=0; } book[1]=1; int min,u; //dijkstra算法核心語句 for(int i=1;i<n;i++){//每次可以求得一個頂點的最短路徑,通過n-1輪即可全部求出 //找到距離源點最遠的未知最短路徑的點,則這點可以確定為最短路徑 min=INF; for(int j=1;j<=n;j++){ if(book[j]!=1&&dis[j]<min){ min=dis[j]; u=j; } } book[u]=1; for(int k=1;k<=n;k++){ if(e[u][k]<INF&&book[k]==0){ if(dis[k]>dis[u]+e[u][k]) dis[k]=dis[u]+e[u][k]; } } } for(int i=0;i<=n;i++){ cout<<dis[i]<<endl; } return 0; }

輸入示例:

6 9
1 2 1

1 3 12

2 3 9

2 4 3

3 5 5

4 3 4

4 5 13

4 6 15

5 6 4

輸出示例:

0

1

8

4

13

17

Dijstra算法為什麽不能處理負邊權問題?

例如:有三條邊 1 3 8, 1 2 9, 2 3 -2;

由於Dijstra算法貪心思想,會先確定3號頂點的最短路徑為8,但是因為有負邊1-2-3的路徑權值為7,所以當有負邊是Dijstra算法不再適用;

Dijkstra算法(最短路)