Dijkstra演算法思想及程式碼
阿新 • • 發佈:2019-01-10
例:求頂點到圖中任意一點的距離最小值
思想: 1.首先初始化一個點到其本身距離為0,到其它點距離為無窮,記錄距離點為e[i][j],初始化所有點; 2.然後,接著初始化頂點到其它點的距離,記為dis[i],在正式表示頂點演算法中dis[i]儲存最小距離。初始化是到某一個點i的距離,初始化方式是dis[i]=e[1][i]; 3.接著,標記元素,沒訪問過的記為Q集合,用visit[i]=0表示;訪問過的記為P集合,用visit[i]=1表示; 4.預處理完畢,第一層迴圈,以i表示1...n-1,裡面的一個迴圈是找到距離i最近的點,標記已經訪問過; 5.裡面的另一層迴圈是找到剛剛找到的距離第i個頂點距離最短的點,記為u;然後找u到v最短距離; 6.如果v點未被列舉且dis[v]>dis[u]+e[u][v],那麼就更新dis[v]的值; 7.繼續遍歷,直到所有元素都被標記為visit[i]=1; https://blog.csdn.net/qq_35644234/article/details/60870719這一篇部落格寫得特別詳細;
#include<bits/stdc++.h> using namespace std; int e[111][111],dis[111],visit[111]; int n,m; const int inf=9999999; void init1() { for(int i=1;i<=n;i++) {//n個點; for(int j=1;j<=n;j++) { if(i==j) e[i][j]=0;//自己到自己距離設定為0 else e[i][j]=inf;//其它兩點間距離為無窮; } } } void init2() { //初始化dis陣列,1號頂點到其餘各個頂點的初始距離 for(int i=1;i<=n;i++) { dis[i]=e[1][i];//1號地點到其它點距離值; } //初始化visit陣列 for(int i=1;i<=n;i++) { visit[i]=0;//預設沒遍歷過點為0 /* 已知最短路程的頂點集合P和未知最短路徑的頂點集合Q vis[i]=1表示在P集合;vis[i]=0表示在Q集合; */ } visit[1]=1;//起點visit[1]初始化為1 } void dijkstra() { int i,j,u,v,min; for(i=1;i<=n-1;i++) { //找離i號頂點最近的頂點 min=inf; for(j=1;j<=n;j++) { if(visit[j]==0&&dis[j]<min) { min=dis[j]; u=j; } } visit[u]=1;//找到1號頂點與之最近的點; for(v=1;v<=n;v++) { if(e[u][v]<inf) {//e[u][v]代表u、v兩點之間距離; if(visit[v]==0&&dis[v]>dis[u]+e[u][v]) //v點沒訪問過並且頂點到其距離大於頂點到u距離加上u、v之間距離; dis[v]=dis[u]+e[u][v];//到哪個點的距離為dis[v]; } } } } int main() { int i,j,t1,t2,t3; cin>>n>>m; init1(); //讀入邊 for(i=1;i<=m;i++) { cin>>t1>>t2>>t3; e[t1][t2]=t3;//讀入的t3是距離值; } init2(); dijkstra();//進行演算法; for(i=1;i<=n;i++) { cout<<dis[i]<<endl; } return 0; }