演算法——最短路徑——Dijkstra演算法
阿新 • • 發佈:2018-12-25
下學期開學大三,是到了該考慮前程的時候了。感覺自己大一大二演算法基礎沒打好,acm也沒參加,成績也不高,唉 所以大三努力吧,接下來就是多看演算法,多寫部落格
每天一個演算法 第一個 Dijkstra演算法
Dijkstra演算法是一個求最短路徑的演算法
作用:求圖中一點到圖的其他所有點的最短路徑,要求路徑全為正的,不能有負值
時間複雜度:O(V^2)
空間複雜度:O(V)
所屬演算法類別:貪心演算法
簡單描述原理:將V(就是已經給出的圖的所有點)分成兩部分,S:已經求出最短路徑的點的集合,T=V-S:尚未求出最短路徑的點的集合,我們所要做的就是將T中的點按照距離遞增的次序加到S中,並將最短距離記錄到D中
具體步驟:
1.初始化S,T:任意取一個點加入到S中,這時S中只有這一個點,其餘點在T中
2.初始化D:對於S中的那一個點來說,如果T中的點有到該點的弧(直接路徑),則D[i]為弧值,否則則D[i]為無窮
3 從T中抽取從目前的D來看距離v0最短的一個點加入到S中
4更新D
5重複3 4直到S=V
程式碼實現:
#include<stdio.h> #include<stdlib.h> #define MAXVER 100 void Dijstra(int n,int v0); int A[MAXVER][MAXVER];//鄰接矩陣 int dist[MAXVER];//儲存最短路徑的距離的陣列 int path[MAXVER];// path[i]為前驅頂點下標,prev[i]的值是"頂點vs"到"頂點i"的最短路徑所經歷的全部頂點中, //位於"頂點i"之前的那個頂點。 bool final[MAXVER];//final[i]=true,表示已求得頂點i的最短路徑 int main(){ int n; //接收資料 printf("輸入行數\n"); scanf("%d",&n); for(int i=0;i<n;i++){ printf("第%d行\n",i); for(int j=0;j<n;j++){ scanf("%d",&A[i][j]); } } Dijstra(n,0); for(int i=0;i<n;i++){ printf("與第%d個點的最短距離是%d\n",i,dist[i]); } } void Dijstra(int n,int v0){//演算法實現函式 for(int i=0;i<n;i++){//初始化dist,即步驟2 dist[i]=A[v0][i]; path[i]=v0; final[i]=false; } dist[0]=0; final[0]=0; for(int i=0;i<n;i++){ int minds=0x7fffffff; int ind=-1; for(int j=0;j<n;j++){//尋找目前的路徑距離中最小的一個 if(!final[j]&&dist[i]<minds){ minds=dist[j]; ind=j; } } final[ind]=true; for(int j=0;j<n;j++){//更新dist if(!final[j]&&minds+A[ind][j]<dist[j]){ dist[j]=minds+A[ind][j]; path[j]=ind; } } } }