算法笔记17:基于队列改进的Bellman-ford算法

改进的Bellman-ford算法

本文承接自算法笔记16:单源最短路径
基于队列的Bellman-ford算法的改进:根据前面讲到,对于边e:v→w,只有distTo[v]改变,distTo[w]才会改变,那么我们不需要放松所有边重复V轮,我们只需要放松可能改变的点,例如在下图中,从起点0开始,只有顶点1 2 3才会改变,那么将1 2 3加入队列去放松,其他顶点的不会改变就不会放松。放松1时将4加入队列,依次进行下去直到队列为空。
在这里插入图片描述
上图中有负权重边,因为负权重边B的影响,形成了蓝色标出的负权重环:总权重为负的有向环。在存在有向环时队列永远无法为空,会在负权重环中一直走不会出来,负权重环中的顶点的distTo[]会越来越小。同样的因为在负权重环中循环,导致edageTo[]中部分如下

edageTo[2] edageTo[4] edageTo[5]
C A B

所以当从edageTo中回溯负权重环中的顶点的最短路径和被负权重环隔开的顶点6的时候是回溯不到起点的,只有1和3能回溯到起点,所以此时我们认为只有1和3存在最短路径。由此可以看到应该存在负权重环的判断以在队列永远非空时结束循环,为此根据edageTo[]中的数据建立最短路径树-一个新的加权有向图,然后根据有向环的判定判定是否存在有向环和从起点是否可达以判断是否存在最短路径。有向环和可达性的程序在 有向图中介绍,下面对加权有向图进行适配修改。

mport java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
/**
 * 加权有向图的深度优先搜索
 * @author XY
 *
 */
public class WeightedDiDFS {
   
	private boolean[] marked;

	public WeightedDiDFS(EdageWeightedDigraph dgraph,int s) {
   
		marked = new boolean[dgraph.V()];
		dfs(dgraph, s);

	}

	private void dfs(EdageWeightedDigraph dgraph, int s) {
   
		marked[s] = true;
		for (WeightedDiEdage e : dgraph.adj(s)){
   
			int x=e.to();
			if (!marked[x])
				dfs(dgraph, x);
		}
			
	}
	public boolean marked(int v){
   
		return marked[v];
	}
	public static void main(String[] args) throws FileNotFoundException {
   
		EdageWeightedDigraph dgraph=new EdageWeightedDigraph(new Scanner
				(new File("E:"+File.separator+"wedigraph.txt")));
		WeightedDiDFS dfs=new WeightedDiDFS(dgraph, 5);
		System.out.println(dfs.marked(7));
	}
}

/**
 * 加权有向图的有向环判定
 * @author XY
 *
 */
public class WeightedDiCycle {
   
	private boolean[] marked;
	private boolean[] turn;//记录一条路径中已经遍历过的顶点
	private boolean hascycle=
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值