1. 程式人生 > >最短路(Floyd演算法)

最短路(Floyd演算法)

最短路徑問題使用Floyd演算法:(結點編號從1-n)

使用鄰接矩陣來儲存原圖,那麼此時鄰接矩陣中edge[i][j]的值即表示從結點i和結點j,中間不經過任何結點時距離的最小值(若他們之間有多條邊,取最小權值儲存在鄰接矩陣,也可能是去無窮或者-1,這樣來表示不可達);在圖的鄰接矩陣表示法中,edge[i][j]表示結點i和結點j中間不經過任何結點時的最短的路徑,那麼依次為中間允許經過的結點新增結點1,結點2.。。直到新增完這些結點,從結點i到結點j就允許經過所有的結點的最短路徑長度就可以確定了,該長度即為由結點i到結點j的最短路徑長度。

下面的程式碼:我自己添加了所經歷的路徑上的節點的輸出,已經註釋掉了,有想看的同學把所有註釋去掉就可以看到最短路徑上經歷了哪些節點!

#include<iostream>
#include<algorithm>
using namespace std;
int ans[101][101];
//int path[101][101];//在i到j的路徑上的j的前一個節點
//int d[101];//最短路徑上經過的節點的編號
const int INF = 100000000;
int main()
{
	int n, m;
	while (cin >> n >> m&&n&&m)
	{
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= n; j++)
			{
				ans[i][j] = INF;//對鄰接矩陣進行初始化,inf代表不可達
				//path[i][j] = -1;
			}
			ans[i][i] = 0;//自己到自己初始化為0
		}
		for (int i = 0; i < m; i++)
		{
			int a, b, c;
			cin >> a >> b >> c;
			ans[a][b] = c;//注意是無向圖,所以賦值操作進行兩次,關於對角線對稱
			ans[b][a] = c;
			//path[a][b] = a;
			//path[b][a] = b;
		}
		for (int k = 1; k <= n; k++)
		{
			for (int i = 1; i < n; i++)
			{
				for (int j = 1; j <= n; j++)
				{
					if (ans[i][j]>ans[i][k] + ans[k][j])
					{
						ans[i][j] = ans[i][k] + ans[k][j];
						//path[i][j] = path[k][j];
					}
				}
			}
		}
		/*int x = n;
		int size = 0;
		d[size++] = n;
		while (path[1][x] != 1)
		{
			x = path[1][x];
			d[size++] = x;
		}
		d[size++] = 1;
		cout << "the shortest path is: " ;
		for (int i = size-1; i >=0; i--)//逆序輸出
			cout << d[i] << " " ;
		cout << endl;
		cout << "the shortest spend is: ";*/
		cout << ans[1][n] << endl;
	}
	return 0;
}