无权图的最短路径问题可以用简单的广度优先算法求解,当对路径赋权后,问题就变得复杂了。
此时可用迪克斯特拉算法求解,该算法为一个贪婪算法。
该算法类似无权最短路径,按节点处理。在每个阶段的节点选取上体现贪婪算法,即每次都选取临时路径长最短的节点,并标记为known。容易证明被标记为known的节点均已得到从起始节点到该节点的最短路径长,因此被标记为known的节点在后续阶段中路径信息将不再更新。
代码如下:
#include<iostream>
using namespace std;
int main()
{
int input[8][8] = {
{0,0,0,0,0,0,0,0},//第一行用于表示是否为known,1表示known
{0,0,2,0,1,0,0,0},
{0,0,0,0,3,10,0,0},
{0,4,0,0,0,0,5,0},
{0,0,0,2,0,2,8,4},
{0,0,0,0,0,0,0,6},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,1,0}
};//代表上图的邻接矩阵
int path[8] = {-1,-1,-1,-1,-1,-1,-1,-1};//用于保存临时最短路径
path[1] = 0; //由path[1]开始计算
int known = 0;
for (int j = 0; j < 7; j++)
{
int tmp = 9999; //代表无限大
for (int i = 1; i < 8; i++)
if (path[i] != -1 && input[0][i] != 1)//path在该位置节点有临时数据,且该节点不为known
if (path[i] < tmp)//选取临时数据中最小的数据节点作为下轮循环的known节点
{
tmp = path[i];
known = i;
}
input[0][known] = 1;
for (int i = 0; i < 8; i++)
if (input[known][i] != 0)
if (path[i] == -1)
path[i] = path[known] + input[known][i];
else
path[i] = path[i] < path[known] + input[known][i] ? path[i] : path[known] + input[known][i];
for (int i = 1; i < 8; i++)
cout << path[i] << " ";
cout << endl;
}
}