这篇文章主要讲解了C++怎么计算任意权值的单源最短路径,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大家阅读完之后会有帮助。
本文实例为大家分享了C++计算任意权值单源最短路径的具体代码,供大家参考,具体内容如下
一、有Dijkstra算法求最短路径了,为什么还要用Bellman-Ford算法
Dijkstra算法不适合用于带有负权值的有向图。
如下图:
用Dijkstra算法求顶点0到各个顶点的最短路径:
(1)首先,把顶点0添加到已访问顶点集合S中,选取权值最小的邻边<0, 2>,权值为5
记录顶点2的最短路径为:dist[2]=5, path[2]=0,把顶点2添加到集合S中。
顶点2,没有邻边(从顶点2出发,其他顶点为终点的边),结束;
(2)访问<0, 1>边,权值为7,把顶点7添加到顶点集合S中,dist[1]=7, path[1]=0。
虽然,顶点1有邻边<1,2>,但是因为顶点2已在集合S中,所以,不继续修改,结束程序。
所以,最终dist[1]=7,dist[2]=5。显然结果不对,顶点2的最短路径应为:0->1->2,权值为7+(-5)=2
二、Bellman-Ford算法思路:
Bellman-Ford算法,效率低,但是适合用于求带有负权值的单源最短路径。
不考虑有回路的,如下图,顶点0到顶点1的最短路径可以无穷小
下面开始简单描述Bellman-Ford的思路:
可以,看到:通过绕过一些顶点,可以取得更短的路径长度
当k=1时,即从源点(顶点0)到其他顶点,只需要一条边。有<0,1>、<0,2>、<0,3>,所以有:dist[1]=6,dist[2]=5,dist[3]=5;
当k=2时,需要2条边的,u=1,有0->2->3,长度为:5+(-2)=3, 更短,所以要修改dist[1]=3;
u=2,有:0->3->2,长度为:5+(-2)=3,更短,所以要修改dist[2]=3;
u=3,没有两条边从顶点0到达顶点3的路径;
u=4,有0->1->4,长度为:6+(-1)=5, 更短,所以要修改dist[4]=5;
u=5,有0->3->5,长度为:5+(-1)=4,更短,所以要修改dist[5]=4;
u=6,没有2条边就可以从顶点0到顶点6的路径。
重复上面步骤,直到k=n-1结束程序。
三、实现程序:
1.Graph.h:有向图
的ifndef Graph_h #定义Graph_h # include & lt; iostream> 使用名称空间性病; const int DefaultVertices=30; 模板& lt;类T类E> 结构体边缘{//边结点的定义 int桌子;//边的另一顶点位置 E成本;//表上的权值 Edge*链接;//下一条边链指针 }; 模板& lt;类T类E> {//顶结构顶点点的定义 T数据;//顶点的名字 Edge *调节;//边链表的头指针 }; 模板& lt;类T类E> 类Graphlnk { 公众: const E maxValue=https://www.yisu.com/zixun/100000;//代表无穷大的值(=? Graphlnk (int深圳=DefaultVertices);//构造函数 ~ Graphlnk ();//析构函数 空白inputGraph ();//建立邻接表表示的图 空白outputGraph ();//输出图中的所有顶点和边信息 T getValue (int i);//取位置为我的顶点中的值 v1 E getWeight (int, int v2);//返回边(v1、v2)上的权值 bool insertVertex (const t顶点);//插入顶点 v1 bool insertEdge (int, int v2, E重量);//插入边 bool removeVertex (int v);//删除顶点 bool removeEdge (v1 int, int v2);//删除边 int getFirstNeighbor (int v);//取顶点v的第一个邻接顶点 v int getNextNeighbor (int, int w);//取顶点v的邻接顶点w的下一邻接顶点 int getVertexPos (const T顶点);//给出顶点顶点在图中的位置 int numberOfVertices ();//当前顶点数 私人: int maxVertices;//图中最大的顶点数 int numEdges;//当前边数 int numVertices;//当前顶点数 顶点 c++怎么计算任意权值的单源最短路径