Dijkstra算法(最短路)
阿新 • • 發佈:2019-02-11
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算法(最短路)