单源点最短路径

    单源最短路径:从顶点v可达顶点u表示为v->u,在所有的可达路径中存在一条权值最小的路径,则这条路径叫做v到u的最短路径。那么单源最短路径指的是:求出给定源点s到其他所有顶点的最短路径。
    最短路径的性质:对于一给定的带权图G=(V,G),所定义的加权函数为w:E->R。设p=<v1,v2,v3,……,vk>是从v1到vk的最短路径。对于任意i,j,其中1<=i<=j<=k,设pij=<vi,vi+1,……,vj>为p中从顶点vi到顶点vj的子路径。那么,pij是从vi到vj的最短路径。(最短路径的子路径是最短路径)
    最短路径中不存在负权回路,因为如果存在负权回路,我们总是可以顺着已经找的“最短”路径,再穿过负权回路而获得一条权值更小的路径。这样无限次的穿过,我们得到这条路径的权值为负无穷。同样,最短路径中也不存在正权回路,对于权值为零的回路可有可无。
    路径松弛性质:如果p=<v0,v1,……,vk>是从s=v0到vk的最短路径,而且p的边按照(v0,v1),(v1,v2),……,(vk-1,vk)的顺序进行松弛,那么d[vk]=sp(s,vk)(表示s到vk的最短路径上的权值),这个性质的保持并不受其他松弛操作的影响,即使它们与p的边上的松弛操作混合在一起也是一样的。
下面介绍三种方法求最短路径:
   (1)Bellman-Ford算法,该算法用来解决一般的单源最短路径问题(边的权值可以为负,但是不存在负权回路)。此方法可以检测是否有存在从源点可达的负权回路。
   (2)在有向无环图中,我们可以根据图中顶点的拓扑顺序,在线性时间内计算出单源最短路径路径的值。
   (3)Dijkstra算法,运行时间比Bellman-Ford算法时间低,但此算法有一个不足之处是:必须要求边上的权值非负。
在介绍上述三个算法之前,我们先介绍两个基本操作:初始化操作和松弛操作。
初始化操作的伪代码:
Initialize-Single-Source(s)
	for each vertex v∈V[G]
		do  d[v] <- ∞
			p[v] <- NIL
	d[s] <- 0;
其中d[v]表示从源点到v的最短路径上权值的上界,p[v]表示最短路径上v的前驱顶点。
松弛操作的伪代码:
Relax(u,v,w)
<span style="white-space:pre">	</span>if d[v] > d[u] + w(u,v)
	   then d[v] <- d[u] + w(u,v)
		p[v] <- u;	
在松弛一条边(u,v)时,要测试是否可以通过u,对目前为止到v的最短路径进行更新。如果可以更新的话,则更新d[v]和p[v]。一次松弛操作可以减少最短路径估计值d[v],并且更新v的前驱p[v]。
方法一:Bellman-Ford算法
对于给定的带权有向图G=(V,G),其源点为s,加权函数为w:E->R,对该图运行Bellman-Ford算法后返回一个布尔值,表明图中是否存在一个从源点可达的负权回路。若存在这样的回路,算法说明该问题无解;若不存在这样的回路,算法将产生最短路径(p[v])及其权值(d[v])。
此算法对所有的边执行|v|-1次松弛操作。经过|v|-1次迭代后,对于s可达的顶点v,都有d[v]=sp(s,v),该算法的时间复杂度为o(VE)。
证明:设v为从s可达的任意顶点,p=<v0,v1,……,vk>是任一条从s到v的最短路径,其中v0=s和vk=v。路径p至多有|v|-1条边,所以k<=|v|-1。在每一次松弛所有边的操作过程中,第i次迭代被松弛的边为(vi-1,vi),由上述的路径松弛性质,可得d[v]=d[vk]=sp(s,v)。
/*Bellman_Frod算法求最短路径*/
#include<iostream>
#include<vector>
#include<fstream>
using namespace std;

//边类
struct Node
{
	int value;//存储边的终点
	int weight;//存储边的权值
	Node(){}
	Node(int value,int weight)
	{
		this->value = value;
		this->weight = weight;
	}
};

vector<vector<Node>> mGraph;//图结构
int
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值