對於給定的帶權有向圖G和源點v,求從v到G中其餘各頂點的最短路徑。該演算法是一個按路徑長度遞增的次序產生最短路徑的演算法。
以下程式碼封裝含產生有向帶權圖,Dijkstra演算法的完整步驟。請參考【動畫示範Dijkstra演算法】。
代碼說明幾點:
1.dist[MaxVertexNum]; //元素dist[i]表示當前所找到的從源點v到終點vi的最短路徑的長度
2.path[MaxVertexNum]; //元素path[i]是一個串,表示當前所找到的從源點v到終點vi的最短路徑.若沒有弧,則置為空白串。
3.s[MaxVertexNum]; //存放源點和已經產生的終點(即集合S),初態為只有一個源點v
初始化帶權有向圖如下:
完整的實現代碼如下:
#include <iostream><br />#include <string><br />#include <stdio.h><br />using namespace std;<br />#define MaxVertexNum 100<br />#define INF 32767<br />typedef struct<br />{<br />char vertex[MaxVertexNum];<br />int edges[MaxVertexNum][MaxVertexNum];<br />int n,e;<br />}MGraph;</p><p>void CreateMGraph(MGraph &G)<br />{<br />int i,j,k,p;<br />cout<<"請輸入頂點數和邊數:";<br />cin>>G.n>>G.e;<br />cout<<"請輸入頂點元素:";<br />for (i=0;i<G.n;i++)<br />{<br />cin>>G.vertex[i];<br />}<br />for (i=0;i<G.n;i++)<br />{<br />for (j=0;j<G.n;j++)<br />{<br />G.edges[i][j]=INF;<br />if (i==j)<br />{<br />G.edges[i][j]=0;<br />}<br />}<br />}<br />for (k=0;k<G.e;k++)<br />{<br />cout<<"請輸入第"<<k+1<<"條弧頭弧尾序號和相應的權值:";<br />cin>>i>>j>>p;<br />G.edges[i][j]=p;<br />}<br />}</p><p>/************************************************************************/<br />/* 迪傑斯特拉演算法 */<br />/************************************************************************/<br />int dist[MaxVertexNum];//元素dist[i]表示當前所找到的從源點v到終點vi的最短路徑的長度<br />string path[MaxVertexNum];//元素path[i]是一個串,表示當前所找到的從源點v到終點vi的最短路徑.若沒有弧,則置為空白串。<br />char s[MaxVertexNum];//存放源點和已經產生的終點(即集合S),初態為只有一個源點v</p><p>void Dijkstra(MGraph G,int v)<br />{<br />int i,k,num,min;char p[2];<br />for (i=0;i<G.n;i++)//初始化dist[],path[]數組<br />{<br />dist[i]=G.edges[v][i];<br />if (dist[i]!=INF)<br />{<br />p[0]=G.vertex[v];//字元轉換為字串,位尾要有結束符<br />p[1]='/0';<br />path[i]+=p;<br />p[0]=G.vertex[i];<br />path[i]+=p;<br />}<br />else<br />{<br />path[i]="";<br />}<br />}<br />s[0]=G.vertex[v];//初始化集合S<br />dist[v]=0;//標記頂點v為源點<br />num=1;//集合S中的頂點個數<br />while (num<G.n)<br />{<br />min=INF;//在dist中尋找最小值元素<br />for (i=0;i<G.n;i++)<br />{<br />if (dist[i]<min && dist[i]!=0)<br />{<br />k=i;<br />min=dist[i];<br />}<br />}<br />if(dist[k]!=0)//輸出可到達的路徑<br />{<br />cout<<dist[k]<<"/t/t"<<path[k]<<endl;<br />}<br />s[num++]=G.vertex[k];//把vk點加入集合中<br />for (i=0;i<G.n;i++)//修改數組dist和path<br />{<br />if (dist[i]>(dist[k]+G.edges[k][i]) && G.edges[k][i]!=INF)<br />{<br />dist[i]=dist[k]+G.edges[k][i];<br />path[i]=path[k];<br />p[0]=G.vertex[i];<br />path[i]+=p;<br />}<br />}<br />dist[k]=0;//置vk頂點為已產生終點標記<br />}<br />}</p><p>int main()<br />{<br />int n;<br />MGraph G;<br />CreateMGraph(G);<br />cout<<"/n請輸入單源點序號:";<br />cin>>n;<br />cout<<"從"<<G.vertex[n]<<"頂點到其他可到達的各點最短路徑為:/n最短路徑/t經過的頂點/n";<br />Dijkstra(G,n);<br />return 0;<br />}
程式測試結果如下: