Bellman-Ford算法笔记

算法介绍:

1、求单源最短路径

    在一个图(就是存放每个节点最小路径值)中,将源点(起始点)到其他点最短路径值计算,其中可能有负权值。

    负权值:就是存在一个负权回路,里面所有的点都是负权的点,意味着这条路是环型对其他路径是不可达的,得到的最短路径值是任意最小数。

2、输入输出

    输入:路径信息(包括起始点,终点,以及路径值,可能需要自己封装),源点,终点

    输出:从 源点 到 终点 最小路径值

3、算法步骤

    1、初始化图:把源点之外节点值都变成+\infty,可以是Integer.MAXVALUE

    2、迭代松弛操作:所谓的松弛操作就是现有橡皮筋圈着两个点p和w,但是v和w更短,就把p点换成v点,橡皮筋变得松弛的意思。就是说next = min(now, val(v,w)),now = val(p, w)。这个就是dp中的状态转移

    3、检查负权:如果发现了负权环,那就意味着不能抵达终点,返回一个错误提示(返回需要的值或提示就行)

相关算法:

P1411-树:https://blog.csdn.net/qq_28033719/article/details/106121253

Cheapest Flights Within K Stops(K次到达目的地最便宜航程):https://blog.csdn.net/qq_28033719/article/details/106758679

背包问题&一百块最少硬币数:https://blog.csdn.net/qq_28033719/article/details/106501253

JAVA代码:

其实就是一个dp用法,但是又多了剪枝的处理,和背包又很相似。

public class BellmanFord {

    public static void main(String[] args) {
        BellmanFord bellmanFord = new BellmanFord();

        int[][] test01 = new int[][]{{0,1,10},{0,2,20},{2,4,200},{4,5,10},{1,3,100},{3,4,50}};

        // 0 - 1 - 3 - 4 - 5 total:170 最小
        // 0 - 2 - 4 - 5 total:230
        System.out.println(bellmanFord.func(6,0, 5, test01));
    }

    public int func(int nodenum, int begin, int end,int[][] edges) {
        // 创建一个和节点数量一致的数组
        int[] dis = new int[nodenum];

        // 初始化图,将非开始节点值变为最大(根据情况)
        int max = 10000000;
        for(int i = 0;i < nodenum;i ++)
            if(i != begin) dis[i] = max;

        // 松弛操作,逐步逼近
        for(int i = 0;i < nodenum;i ++)
            for(int j = 0;j < edges.length;j ++) {
                int[] edge = edges[j];
                dis[edge[1]] = Math.min(dis[edge[1]], dis[edge[0]] + edge[2]);
            }

        return dis[end] >= max ? -1 : dis[end];
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值