【知识点4】Bellman-Ford算法和SPFA算法⭐⭐⭐⭐⭐

本文详细介绍了Bellman-Ford算法和SPFA算法,前者用于解决含有负权边的单源最短路径问题,后者则是在Bellman-Ford基础上的优化,通过队列实现减少冗余操作,提高效率。


今天也是为了cc,努力奋斗的一天ヾ(≧▽≦*)o

1. Bellman-Ford算法

引言

前面在学习Dijkstra算法时提到,Dijkstra算法不适用于边的权值为负数的情况。为了解决这个负边权这个问题,就需要使用Bellman-Ford算法(简称BF算法)。和Dijkstra算法一样,Bellman-Ford算法可解决单源最短路径问题,而且在此基础上也能处理负边权的情况。

基本思想

与Dijkstra算法相同,Bellman-Ford算法设置一个数组d,用来存放从源点到达各个顶点的最短距离。同时Bellman-Ford算法返回一个bool值:如果其中存在从源点可达的负环,那么函数将返回false;否则,函数将返回true,此时数组d中存放的值就是从源点到达各顶点的最短距离。

伪代码

需要对图中的边进行 V − 1 V-1 V1轮操作,每轮都遍历图中的所有边:对每条边u -> v,如果以u为中介点可以使d[v]最小,即d[u]+length[u -> v] < d[v]成立时,就用d[u] + length[u -> v]更新d[v]。同时也可以看出,Bellman-Ford算法的时间复杂度是O(VE),其中V是顶点的个数,E是边数。

for(i = 0;i < n - 1;i++){
   
   	//执行n-1轮操作,其中n为顶点数 
	for(each edge u->v){
   
   	//每轮操作都遍历所有边 
		if(d[u] + length[u -> v] < d[v]){
   
   	//以u为中介点可以使d[v]更小 
			d[v] = d[u] + length[u -> v];	//松弛操作 
		}
	} 
} 

此时,如果图中没有从源点可达的负环,那么数组d中的所有值都应当已经达到最优。因此,如下面的伪代码所示,只需再对所有边进行一轮操作,判断是否有某条边u -> v仍然满足d[u] + length[u->v] < d[v],如果有,则说明图中有从源点可达的负环,返回false;否则,说明数组d中的所有值都已经达到最优,返回true。

for(each edge u -> v){
   
   	//对每条边进行判断 
	if(d[u] + length[u -> v] < d[v]){
   
   	//如果仍可以被松弛 
		return false;	//说明图中有从源点可达的负环 
	}
	return true;
} 

邻接表实现

由于Bellman-Ford算法需要遍历所有的边,显然使用邻接表会比较方便;如果使用邻接矩阵,则时间复杂度会上升到 O ( V 3 ) O(V^3) O(

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值