最短路徑:對於網圖來講,最短路徑是指兩個頂點之間通過的邊上權值之和最少的路徑,而且咱們稱路徑上的第一個頂點式源點,最後一個頂點是終點。如下圖爲例,html
尋找v0到v8的最短距離。算法
對應解決思路:如今比較成熟的有Dijkstra(迪傑斯特拉)算法和Flord算法算法。
post
Dijkstra求源節點S到終結點D的最短距離的過程當中,循環過程當中每次肯定一個源節點到其它節點T的最短距離。該距離肯定後,遍歷判斷該節點T到其它節點的距離是否比如今S到其它節點距離短,更短的話則修改成相應長度,並將對應的路徑記錄。。這種求最短路徑的方式與圖最小生成樹算法之Kruskal(克魯斯卡爾)算法有殊途同歸之妙。該算法的時間複雜度度是O(N^2),N是節點的個數。spa
代碼以下:.net
int dist[MAXNUM];
int prevT[MAXNUM];
int final[MAXNUM];
int MIN;
int G[9][9]={0,1, 5, MAXINT ,MAXINT, MAXINT, MAXINT, MAXINT, MAXINT,//對應的權值矩陣
1, 0, 3, 7, 5, MAXINT ,MAXINT, MAXINT ,MAXINT,
5 ,3, 0, MAXINT ,1 ,7, MAXINT ,MAXINT ,MAXINT,
MAXINT, 7, MAXINT ,0, 2, MAXINT, 3 ,MAXINT, MAXINT,
MAXINT ,5, 1, 2, 0, 3 ,6, 9, MAXINT,
MAXINT, MAXINT ,7, MAXINT, 3, 0, MAXINT, 5, MAXINT,
MAXINT ,MAXINT ,MAXINT, 3, 6, MAXINT, 0 ,2 ,7,
MAXINT, MAXINT ,MAXINT, MAXINT, 9 ,5 ,2, 0, 4,
MAXINT, MAXINT ,MAXINT, MAXINT, MAXINT, MAXINT ,7, 4, 0};
void Short_Dijkstra() { //初始化dist和prevT int min_num; for(int i=0;i<MAXNUM;i++) { final[i]=0;//標記是不是最短路徑 dist[i]=G[0][i];//對應權值 prevT[i]=0; } final[0]=1;//對v0自己就是最短的 dist[0]=G[0][0]; for(int i=1;i<MAXNUM;i++)//每次遍歷v0到某個頂點最短距離 { MIN=MAXINT;//最小值 min_num=0; for(int j=1;j<MAXNUM;j++) { if(!final[j] && dist[j]<MIN) { min_num=j; MIN=dist[j];//最小值 } } final[min_num]=1;//找到最小值 for(int k=0;k<MAXNUM;k++) { if(!final[k] && (G[min_num][k]+dist[min_num]<dist[k])) //在已有的點上找到距離V0更短的距離 { prevT[k]=min_num;//記錄通過的前驅點 dist[k]=G[min_num][k]+dist[min_num];//更新距離 } } } }
Flord算法code
Floyd算法是一個經典的動態規劃算法,它適用於尋找各個頂點之間的最短距離。從任意節點i到任意節點j的最短路徑不外乎2種可能,1是直接從點i到點j,這種方法最直接,可是距離比必定最短。2是從i通過若干個節點k到j。因此,咱們假設Dis(i,j)爲節點i到節點j的最短路徑的距離,對於每個節點k,咱們檢查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,若是成立,證實從i到k再到j的路徑比i直接到j的路徑短,咱們便設置Dis(i,j) = Dis(i,k) + Dis(k,j),同時記錄咱們走過的路徑。這樣一來,當咱們遍歷完全部節點k,Dis(i,j)中記錄的即是i到j的最短路徑的距離。算法時間複雜度:O(n3)。htm
代碼以下blog
void Short_Dijkstra() { //初始化dist和prevTT int min_num; for(int i=0;i<MAXNUM;i++) { final[i]=0; dist[i]=G[0][i]; prevT[i]=0; } final[0]=1;//對v0自己就是最短的 dist[0]=G[0][0]; for(int i=1;i<MAXNUM;i++)//每次遍歷v0到某個頂點最短距離 { MIN=MAXINT;//最小值 min_num=0; for(int j=1;j<MAXNUM;j++) { if(!final[j] && dist[j]<MIN) { min_num=j; MIN=dist[j];//最小值 } } final[min_num]=1;//找到最小值 for(int k=0;k<MAXNUM;k++) { if(!final[k] && (G[min_num][k]+dist[min_num]<dist[k])) //在已有的點上找到距離V0更短的距離 { prevT[k]=min_num;//記錄通過的前驅點 dist[k]=G[min_num][k]+dist[min_num];//更新距離 } } } }
圖這兩種算法最核心的思想就是:利用已有的最短的距離路徑,經過這路徑來不斷擴充,最終實現從原點S到終點D的尋找過程。v8