如何记录Dijkstra最短路径的过程

   

Dijkstra算法     假设找出v0到其他顶点的最短路径     s[N]初始化为0,如果找到v0到vn的最短路径则把s[n]置一     dist[N]初始化为v0到其他顶点的直接路径,两个没相连的顶点用MAX值代入     1.从所有未找到最短路径的顶点中找出dist最小的数值的下标u,所以s[u]置位。     2.用v0到vu的长度加上vu到其他顶点的长度,如果发现比dist中的小,则更新dist中的数值,但注意此时无需把s[]置位,因为此时得到的并不一定是最短路径。然后跳回1,重新检查v0到s[]中还没被置位的顶点。

通过算法我们可以写代码算出各个最短路径的数值,可是问题来了:最短路径是得到了,可是最短路径该怎么走,我们却还是不知道。总不能再写出多个可能路径,再一一检查距离值和最短路径值是否相同吧。这样得到的结果显然没有太多实际意义。 其实,在之前分析的算法当中,least_dst = dist[u];dist[i] = least_dst + v[u][i];已经包含了顶点到顶点的信息,那么只要把这些信息记录下来,最短路径的过程也就得到了。 那么应该采取什么数据结构来记录这些数据呢?经过了一天多的思考和反复的试验,我最终采用了队列。每个起点到顶点的路径都对应一个记录经历过什么顶点的队列。
为 什么选择队列?因为每次更新路径时,其实就是把最短路径经历过的顶点再加上新的终点(在程序中,最终顶点是在确定为最短路径时才入队列的)。而使用队列的 出列和入列,就能做到既把顶点值给其他的队列,又能保证本身队列中顶点值按原先顺序存放(每次出列前判断是否是队头元素,如果不是才出列)。 在每次更新前都要清空队列,这样才能使队列记录有效的顶点。当运算得出各个最短路径时,最短路径的过程也就得到了。

#define INF    const static int v[N][N] = {...};    int find_least(int array[], int s[])  {      int min;      int i;      int flag = 0;        for (i = 0; i < N; i++)      {          if (0 == s[i])          {              if (!flag)              {                  flag = 1;                  min = i;              }              else              {                  if (array[i] < array[min])                  {                      min = i;                  }              }          }      }        return min;  }    int main(void)  {      int s[N] = {0};      int dist[N];      int start_vet;      int u;      int least_dst;      int i;      int count = 0;      int temp;      sequeue* record[N];        printf("input the vertex to start: ");      scanf("%d", &start_vet);           for (i = 0; i < N; i++)      {          dist[i] = v[start_vet][i];          record[i] = CreateSequeue();          EnQueue(record[i], start_vet);      }      s[start_vet] = 1;           while (count++ < N - 1)      {          u = find_least(dist, s);          least_dst = dist[u];          s[u] = 1;          EnQueue(record[u], u);          for (i = 0; i < N; i++)          {              if (least_dst + v[u][i] < dist[i])              {                  dist[i] = least_dst + v[u][i];                  ClearSequeue(record[i]);                  EnQueue(record[i], start_vet);                  temp = DeQueue(record[u]);                  EnQueue(record[u], temp);                  while (GetTopQueue(record[u]) != start_vet)                  {                      temp = DeQueue(record[u]);                      EnQueue(record[i], temp);                      EnQueue(record[u], temp);                  }              }          }      }        //record output           return 0;  }

时间: 2024-10-21 21:44:05

如何记录Dijkstra最短路径的过程的相关文章

dijkstra 最短路径算法

Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低. Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等. 其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合.一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知. 初始时,S

Dijkstra最短路径算法[贪心]

Dijkstra算法的标记和结构与prim算法的用法十分相似.它们两者都会从余下顶点的优先队列中选择下一个顶点来构造一颗扩展树.但千万不要把它们混淆了.它们解决的是不同的问题,因此,所操作的优先级也是以不同的方式计算的:Dijkstra算法比较路径的长度,因此必须把边的权重相加,而prim算法则直接比较给定的权重. 源最短路径问题给定一个带权有向图 G=(V,E) ,其中每条边的权是一个非负实数.另外,还给定 V 中的一个顶点,称为源.现在我们要计算从源到所有其他各顶点的最短路径长度.这里的长度

【Android实战】记录自学自定义GifView过程,能同时支持gif和其他图片!【实用篇】

之前写了一篇博客,<[Android实战]记录自学自定义GifView过程,详解属性那些事![学习篇]> 关于自定义GifView的,详细讲解了学习过程及遇到的一些类的解释,然后完成了一个项目,能通过在xml加入自定义 view (MyGifView)中加入自定义属性(my:gif_src = "@drawable/coffee"),达到播放gif图片的效果. 但是,有几个问题 1.gif_src 属性只支持 gif 图,并不支持其他类型的图片 2.只支持默认的引用图片,不

hdu1548 A strange lift(bfs 或Dijkstra最短路径)

1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #define M 205 6 #define INF 0x3f3f3f3f 7 using namespace std; 8 9 int map[M][M]; 10 int d[M], vis[M]; 11 int n; 12 int b, e; 13 14 void Dijkstra(){

Dijkstra最短路径算法

求下图中的1号顶点到2.3.4.5.6号顶点的最短路径. 与Floyd-Warshall算法一样这里仍然使用二维数组e来存储顶点之间边的关系,初始值如下. 我们还需要用一个一维数组dis来存储1号顶点到其余各个顶点的初始路程,如下. 我们将此时dis数组中的值称为最短路的“估计值”. 既然是求1号顶点到其余各个顶点的最短路程,那就先找一个离1号顶点最近的顶点.通过数组dis可知当前离1号顶点最近是2号顶点.当选择了2号顶点后,dis[2]的值就已经从“估计值”变为了“确定值”,即1号顶点到2号顶

基础算法之Dijkstra最短路径

核心思想:以起始原点为中心,想外层扩展,知道扩展到重点为止. 设到A点的最短路径上,A点前驱节点为B,则该路径包含到达节点B的最短路径. S集合代表已经探索过的节点,U集合表示未探索过的节点. 时间复杂度为O(n^2) 具体过程见下图和表 C++代码如下: 1 #include<stdio.h> 2 #define MAXDIS 4294967295 3 using namespace std; 4 5 class MatrixGraphic{ 6 public: 7 MatrxiGraphi

Dijkstra 最短路径算法 秒懂详解

想必大家一定会Floyd了吧,Floyd只要暴力的三个for就可以出来,代码好背,也好理解,但缺点就是时间复杂度高是O(n³). 于是今天就给大家带来一种时间复杂度是O(n²),的算法:Dijkstra(迪杰斯特拉). 这个算法所求的是单源最短路,好比说你写好了Dijkstra的函数,那么只要输入点a的编号,就可算出图上每个点到这个点的距离. 我先上一组数据(这是无向图): 5 6 1 2 5 1 3 8 2 3 1 2 4 3 4 5 7 2 5 2 图大概是这个样子: 我们以1为源点,来求所

记录apache的安装过程中的一些错误解决方式

安装过多次APACHE,每次安装都会发生一些错误,按着错误一搜,跟着解决方案一步一步就解决了.当然有一些解决方案是坑人的 =.= 这次想想还是把过程记录一下,以防下次使用时有过往成功的记录可查,省的再去找了. APR  not found #  cd /opt #  wget http://archive.apache.org/dist/apr/apr-1.4.5.tar.gz #  tar -zxf apr-1.4.5.tar.gz #  cd  apr-1.4.5 #  ./configur

【算法日记】Dijkstra最短路径算法

上一篇再说广度优先搜索的适合提到了图. 狄克斯拉特算法是在图的基础上增加了 加权图的概念.就是节点和节点之间是有不同距离的 1.算法实例 用Dijkstra算法找出以A为起点的单源最短路径步骤如下 算法实现 # Dijkstra算法--通过边实现松弛 # 指定一个点到其他各顶点的路径--单源最短路径 # 初始化图参数 G = {1:{1:0, 2:1, 3:12}, 2:{2:0, 3:9, 4:3}, 3:{3:0, 5:5}, 4:{3:4, 4:0, 5:13, 6:15}, 5:{5:0