求最短路径的dijkstra算法(详细算法原理自行百度,本文简单从动态规划角度思考),可以看成是一个动态规划的方法。
动态规划算法通常基于一个递推公式及一个或多个初始状态。当前子问题的解将由上一次子问题的解推出。
dijkstra虽然没有递推公式,但是满足将大问题分解成子问题,当前问题的解由上一次子问题的解推出。
算法的思想是
使用了三个一维数组,分别是visit[k],pre_node[k],short[k]来分别表示是否经过k点,k点的前驱节点,到达k点的最短距离
初始状态,是所有点出了起点都没经过,所有点的前驱节点都是起点,到达所有点的最短距离是起点直达的距离(没有路径距离就是极大值)。
接着开始循环求子问题。
子问题是先找出没有经过的并且到起点最短距离不是极大值的点i(第一次肯定是离起点最近的点)
如果找不到这个点,跳出循环(结束循环的唯一条件,这样可以避免非联通图出错)
然后分别找出点i的邻点j,判断通过i到j的距离是否小于目前j到起点的距离
如果是,那就更新short[j]和pre_node[k]
最后可以通过pre_node[]来遍历最短路径
int minlength(int (*edge)[7])
{
int short_p[7];
int pre_node[7];
int visit[7];
for (int i = 1; i < 7; i++){
visit[i] = 0;
pre_node[i] = 1;//起点是1,初始化都从1开始,直接从起点到各个点是老路
short_p[i] = edge[1][i];
}
short_p[1] = 0;
visit[1] = 1;
//for (int v = 0; v < 7; v++){//无法避免不是联通图的情况
while (1){
int min = max_n;
int k = -1;
for (int i = 2; i < 7; i++){
//先找出没进过的并且离起点最近的点
if (!visit[i] && short_p[i] < min){
min = short_p[i];
k = i;
}
}
if (k == -1)
break;//找不到就跳出去,因为可能图不连通
else
visit[k] = 1;
for (int ii = 2; ii < 7; ii++){
//以上面找到的点为基准,找出相邻没过的点,检查过这个点到相邻点近还是老路近
if (!visit[ii] && edge[k][ii] + min < short_p[ii]){
short_p[ii] = edge[k][ii] + min;
pre_node[ii] = k;//更改前节点
}
}
}
return 0;
}
int main()
{
int edge[7][7] = { max_n };
for (