ACM算法:迪傑斯特拉最短路徑

迪傑斯特拉的用途:迪傑斯特拉算法用於求出圖中一個結點到其他所有結點的最短路徑。迪傑斯

特拉算法是求最短路徑中較爲常用的算法,而且方便使用易於理解,很適合用來當成最短路徑入

門的模板實例算法。無論是在有向圖還是無向圖,都有它的優勢之處。


迪傑斯特拉的思路:迪傑斯特拉算法的思路非常的清晰,我結合圖解來解釋(圖是網上找的,如

有雷同,純屬巧合)

先解釋各個字母所代表的意思:S代表已經找到了最短路徑的點,u代表目前的點到所連接的最短路徑的點,dist儲存目前起始點到該點的最短路徑。

(起始點爲“1”)


邏輯主線:

第一步:將與起始點直接連接的點的距離儲存在dist數組中,找出到其中最短路徑的點。如圖中的點“2”,則10就是點“1”到點“2”的最短路徑,因爲從“1”經過其他點間接連接點“2”的點一定會比10 大(仔細想想就知道了)。


第二步:將(點“2”直接連接的點的距離 + 10)儲存在dist數組中,如果原先數組中該點所在的位置已經有值,則比較,新值更小則替換。其中dist數組中值最小的點就是起始點到該點的最短距離,如圖中sist[4]。


之後重複第二步的操作,直到將結點全部遍歷。


注:每找出一個最短距離就將該點標記爲一遍歷,也就說需要(結點書-1)次循環



附上代碼說明:

/*迪傑斯特拉算法求某個頂點到其餘頂點的最短路徑*/
/*代碼示例使用鄰接矩陣來展示*/
void DIJ(MGraph &G, int v)
{
	int i, j, k, min;
	int final1[MAX_VERTEX_NUM];//該數組用來標識頂點是否已確定了最短路徑  
	int dist[MAX_VERTEX_NUM];
	string path[2 * MAX_VERTEX_NUM];
	for (i = 0; i<G.vexnum; i++)
	{//初始化工作  
		dist[i] = G.edges[v][i];//dist數組用來存儲當前找到的v到其他各頂點的最短路徑  
		if (dist[i]<MAX)
			path[i] = G.vexs[v] + G.vexs[i];//如果v到i有邊的話,把頂點字符存到path字符數組中,表示路徑  
		else
			path[i] = "";
		final1[i] = 0;//初始化標識數組爲0  
	}
	dist[v] = 0;
	final1[v] = 1;
	for (j = 1; j<G.vexnum; j++)
	{
		min = MAX;
		for (i = 0; i<G.vexnum; i++)
			if (dist[i]<min && final1[i] == 0)
			{
				min = dist[i];
				k = i;
			}//找到dist數組中最小值的位置k  
		cout << path[k] << " " << dist[k] << endl;//輸出最短路徑  
		final1[k] = 1;//設置標誌位  
		for (i = 0; i<G.vexnum; i++)
		{//遍歷每個頂點i和當前的已求出的最短路徑的頂點k作比較,若從源點經過頂點k到頂點i的路徑,比dist[i]小,  
		 //則更新頂點dist[i]  
			if (dist[i]>dist[k] + G.edges[k][i] && final1[i] == 0)
			{
				dist[i] = dist[k] + G.edges[k][i];
				path[i] = path[k] + G.vexs[i];
			}
		}//從整體上來看就是算出k的鄰接點的當前最短路徑  
	}
}


總結:迪傑斯特拉算法的便利性以及其思路的清晰性得到了很高的認可,屬於數據結構中常用、

也是ACM求最短路徑的入門首選,需要我們去掌握。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章