图的最优化问题:最小生成树、最短路径

典型的图应用问题

无向连通加权图的最小生成树

有向/无向加权图的最短路径

四个经典算法

Kruskal算法、Prim算法---------------最小生成树

Dijkstra算法、Floyd算法-------------最短路径

单源最短路径问题(单源路径问题)

求某指定顶点(称为源点)到其余各顶点的最短路径问题。

Dijkstra算法

思想:与Prim算法类似,采用路径延伸法。求解过程中,将顶点分成生长点和非生长点

生长点:源点s和已确定最短路径的顶点

非生长点:未确定最短路径的顶点

使用待定路径表

步骤:

步骤1)构造初始待定路径表

对每个非生长点v(共n-1个),定初值:P(v)=sv,D(v)=边<s,v>的长度C<s,v>,如果边<s,v>不存在,则认为其长度为∞。

步骤2)循环n-2遍

①选择最短的待定路径

从待定路径表中选出一条最短的,设其为s到v的路径P(v),其长度为D(v),该路径便是s到v的最短路径,v变成为新的生长点。

②修改待定路径表

对剩下的每个非生长点w

设其待定路径为P(w),长度为D(w)

比较D(w)与D(v)+C<v,w>的大小,这里的v是新生长点,如果D(w)≤D(v)+C<v,w>什么也不做,否则,将D(w)改为D(v)+C<v,w>,同时将P(w)改为P(v)接w,表示从s到v后再到w,比原来从s到w(不过v)更短。

示例

以上是官方示例,Dijkstra算法的实现过程。下面是世俗的观点解析。

1. Dijkstra算法与Prim算法类似,都是利用不断寻找新的生长点。

2.再把新的生长点的路径权值(所经过的路径的权值都要相加)与原生长点路径权值比较。再确定是否替换。

3. Dijkstra算法是有向图,要特别注意方向。

步骤:

1.确定一个源点。即从哪一点开始出发。

2.记录与源点有关的其他结点,且源点为出度。如:F->A、F->B、F->C,注意D->F是以F为入度,所以不记录。

3.观察所以与源点有关的边,选择其中最小权值的边进行遍历,而边的另一个结点作为新的生长点。如:F->A  130、F->B  24、F->C  6,因此选择F->C,则C作为新的生长点。

3.利用深度优先的思想,对C结点的相关结点进行递归。(要注意方向)。

4.直到不能递归的结点。如:D结点。此时要注意:一定要返回源点,源点。不能是C结点。

5.回到源点后,利用广度优先的思想,对源点的其他边再遍历(按权值小到大的方式进行)。

F->B 24 F->A 130,所以选择F->B路径,B作为新的生长点。

6.重复以上步骤。。。。。。。

实现Dijkstra算法的存储结构

图可用邻接表存储,结点结构如下:

Dijkstra算法的程序实现

说明:采用“父亲链域法”存储Dijkstra最短路径树

图用邻接表存储,各非生长点的邻接表的表头结点做成带表头监督元结点的双向循环静态链表,兼作待定路径表(便于删除),下标作为顶点序号。

for(v=0; v<=n; v++)

{ L[v].dist=MAXNUM;  //无穷大

L[v].father=s;

L[v].Llink=v-1;     L[v].Rlink=v+1;

}

L[0].Llink=n;

L[n].Rlink=0;  // 以上构造初始链表

L[L[s].Llink].Rlink=L[s].Rlink;

L[L[s].Rlink].Llink=L[s].Llink; //删去源点s

p=L[s].firstarc;

while(p!=NULL)

{ v=p->adjvex;  // v是s的邻接点

L[v].dist=p->cost;

p=p->next;

}

25最短路径之Dijkstra算法的更多相关文章

  1. 【算法设计与分析基础】25、单起点最短路径的dijkstra算法

    首先看看这换个数据图 邻接矩阵 dijkstra算法的寻找最短路径的核心就是对于这个节点的数据结构的设计 1.节点中保存有已经加入最短路径的集合中到当前节点的最短路径的节点 2.从起点经过或者不经过 ...

  2. 单源最短路径(dijkstra算法)php实现

    做一个医学项目,当中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路例如以下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么( ...

  3. 数据结构与算法--最短路径之Dijkstra算法

    数据结构与算法--最短路径之Dijkstra算法 加权图中,我们很可能关心这样一个问题:从一个顶点到另一个顶点成本最小的路径.比如从成都到北京,途中还有好多城市,如何规划路线,能使总路程最小:或者我们 ...

  4. 最短路径 | 深入浅出Dijkstra算法(一)

    参考网址: https://www.jianshu.com/p/8b3cdca55dc0 写在前面: 上次我们介绍了神奇的只有五行的 Floyd-Warshall 最短路算法,它可以方便的求得任意两点 ...

  5. 经典树与图论(最小生成树、哈夫曼树、最短路径问题---Dijkstra算法)

    参考网址: https://www.jianshu.com/p/cb5af6b5096d 算法导论--最小生成树 最小生成树:在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树. im ...

  6. 【算法导论】单源最短路径之Dijkstra算法

    Dijkstra算法解决了有向图上带正权值的单源最短路径问题,其运行时间要比Bellman-Ford算法低,但适用范围比Bellman-Ford算法窄. 迪杰斯特拉提出的按路径长度递增次序来产生源点到 ...

  7. 最短路径问题---Dijkstra算法详解

    侵删https://blog.csdn.net/qq_35644234/article/details/60870719 前言 Nobody can go back and start a new b ...

  8. 0016:单源最短路径(dijkstra算法)

    题目链接:https://www.luogu.com.cn/problem/P4779 题目描述:给定一个 n 个点,m 条有向边的带非负权图,计算从 s 出发,到每个点的距离. 这道题就是一个单源最 ...

  9. ACM: HDU 3790 最短路径问题-Dijkstra算法

    HDU 3790 最短路径问题 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Des ...

随机推荐

  1. Windows正向绑定shell和反向反弹shell的Python代码

    Windows下的shell原理 经过查阅资料,使用os.dup2(nfd, ofd)的方式重定向socket的输入输出到windows系统的cmd是无法做到的,属于系统原因,不能直接复制Linux下 ...

  2. 内网渗透中的NTLM-Hash Relay

    基础知识 NTLN和Net-NTLM 1.NTLM(V1/V2)的hash是存放在安全账户管理(SAM)数据库以及域控的NTDS.dit数据库中,获取该Hash值可以直接进行PtH攻击,我博客中前文也 ...

  3. FPGA时序约束的几种方法 (转)

    FPGA时序约束的几种方法 对自己的设计的实现方式越了解,对自己的设计的时序要求越了解,对目标器件的资源分布和结构越了解,对EDA工具执行约束的效果越了解,那么对设计的时序约束目标就会越清晰,相应地, ...

  4. 【CF873F】Forbidden Indices 后缀自动机

    [CF873F]Forbidden Indices 题意:给你一个串s,其中一些位置是危险的.定义一个子串的出现次数为:它的所有出现位置中,不是危险位置的个数.求s的所有子串中,长度*出现次数的最大值 ...

  5. Unity3D Mecanim :Body Mask的使用、 角色Retargeting原理分析、Apply RootMotion

    一.Body Mask的使用 1.1.配置好骨骼后通过Muscles来微调角色骨骼中的运动范围,以避免角色在动画中的不正确的叠加或失真等现象. 1.2.身体遮罩BodyMask更形象的描述就是身体的开 ...

  6. 【笔记】javascript权威指南-第二章-词法结构

    词法结构 //本书是指:javascript权威指南    //以下内容摘记时间为:2013.7.28   字符集 UTF-8和UTF-16的区别?Unicode和UTF是什么关系?Unicode转义 ...

  7. iOS - 使用苹果自带的UIVideoEditController进行视频编辑

    UIVideoEditorController类包含了由系统提供的界面,使用户可以交互式的剪切视频.UIVideoEditorController对象处理用户的交互并且提供把编辑后的视频的文件系统路径 ...

  8. vim ctrl+v垂直选取产生 e353错误

    原因是/etc/vim/vimrc中map ctrl+v为其他作用了 解决方法: 删除掉map<C-V>...项即可

  9. Java 多线程 ---- 线程中this与 Thread.currentThread()线程的区别

    总结起来一句话:在Thread中调用this其实就是调用Thread私有Runnable类型的target,target是Thread类的一个属性,而Thread.currentThread()是指新 ...

  10. POJ_3186_Treats for the Cows

    Treats for the Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6568   Accepted: 34 ...