戴克斯特拉算法:(英語:Dijkstra's algorithm,又譯迪傑斯特拉算法)由荷蘭計算機科學家艾茲赫爾·戴克斯特拉在1956年提出。戴克斯特拉算法使用了廣度優先搜索解決賦權有向圖的單源最短路徑問題。
如圖為一個有權無向圖,起始點1到終點5,求最短路徑
lowcost數組存儲下標點到起始點的最短距離,mst數組標記該點是否已標記,
如下圖,遍歷graph數組找出初始點(點1)與個點之間的距離存入lowcost(距離<lowcost存入),*為無窮大
遍歷lowcost數組,找出最小值並且沒有被標記過(mst != 0),找出的最小值的點標記(mst = 0),sum=4
遍歷graph數組,存入lowcost中(注意:8到2的距離+sum<lowcost[8],所以lowcost[8]=graph[2][8]+sum) 注意:mst[1]是等於0的,下面都是0
遍歷lowcost數組,找出最小值,sum=7
以下都依次類推...
輸入:
9 14 1 5
1 2 4
1 8 8
2 8 3
2 3 8
8 9 1
8 7 6
3 9 2
9 7 6
3 4 7
3 6 4
7 6 2
4 6 14
4 5 9
6 5 10
輸出:
24
代碼:
#include <iostream> #include <bits/stdc++.h> using namespace std; #define MAX 100 #define MAXCOST 0x7fffffff //int型最大值 void prim(int graph[][MAX],int n,int start,int end) { int lowcost[MAX]; int mst[MAX]; int sum=0; for(int i=1;i<=n;i++)//將與各點與起始點的距離存入lowcost中 { lowcost[i]=graph[start][i]; mst[i]=1; } mst[start]=0; //起始點被標記 for(int i=1;i<=n;i++) { if(mst[end]==0)//終點被標記結束 { cout<<sum; break; } int min=MAXCOST; int minid=0; for(int j=1;j<=n;j++)//遍歷lowcost數組,找最小值 { if(lowcost[j]<min && mst[j]!=0) { min=lowcost[j]; //最小值 minid=j; //最小值下標 } } //cout<<"V"<<mst[minid]<<"-V"<<minid<<"="<<min<<endl; sum=min; //cout<<sum<<endl; mst[minid]=0; //最小值下標點被標記 for(int j=1;j<=n;j++)//找最小值點與各點的距離 { if(graph[minid][j]==MAXCOST)//如果此點與最小值點沒有聯系(距離為最大值)則lowcost不變,跳過 { continue; } else if(graph[minid][j]+sum<lowcost[j] && mst[j]!=0)//此點與最小點有聯系,並且+sum<lowcost 並且此點沒有被標記,則賦值給lowcost { lowcost[j]=graph[minid][j]+sum; } } } } int main() { int n,m; int start,end; int graph[MAX][MAX]; cin>>n>>m>>start>>end; //初始化圖G for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { graph[i][j]=MAXCOST; } } //構建圖G for(int k=1;k<=m;k++) { int i,j,cost; cin>>i>>j>>cost; graph[i][j]=cost; graph[j][i]=cost; } prim(graph,n,start,end); return 0; }