Dijstra和Bellman_ford

Dijstra算法是求图中的最短路径,也就是最短路径算法(在有权图(权值非负数)中求从起点到其他节点的最短路径算法。)

它采用的是贪心的思想,每次选择距离最近的地点,也就是说他每一次都是只考虑当前利益并且选定了后续也不能再更改,这样也许会错过总体来说更小的路径

需要注意的是:

  • dijkstra 算法可以同时求 起点到所有节点的最短路径
  • 权值不能为负数

dijkstra三部曲

  1. 第一步,选源点到哪个节点近且该节点未被访问过
  2. 第二步,该最近节点被标记访问过
  3. 第三步,更新非访问节点到源点的距离(即更新minDist数组)

代码:

java 复制代码
import java.util.Arrays;
import java.util.Scanner;

public class dijkstra {
    public static void main(String[] args){
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        int m=scanner.nextInt();
        int[][] grid=new int[n+1][n+1];
        for(int i=0;i<=n;i++){
            Arrays.fill(grid[i],Integer.MAX_VALUE);
        }
        for(int i=0;i<m;i++){
            int v=scanner.nextInt();
            int u=scanner.nextInt();
            int val=scanner.nextInt();
            grid[v][u]=val;
        }
        int[] midDist=new int[n+1];
        Arrays.fill(midDist,Integer.MAX_VALUE);
        midDist[1]=0;
        boolean[] visited=new boolean[n+1];
//        遍历每一个节点,每次循环都会选取一个未访问过的节点
        for(int i=1;i<=n;i++){
            int minVal=Integer.MAX_VALUE;
            int cur=1;
//            第一步选距离原点最近且未访问过的节点
            for(int j=1;j<=n;j++){
                if(!visited[j]&&midDist[j]<minVal){
                    minVal=midDist[j];
                    cur=j;
                }
            }
//            第二步标记该节点已经访问
            visited[cur]=true;
//            第三步更新未访问节点到原点的距离
            for(int j=1;j<=n;j++){
                if(!visited[j]&&grid[cur][j]!=Integer.MAX_VALUE&&midDist[cur]+grid[cur][j]<midDist[j]){
                    midDist[j]=midDist[cur]+grid[cur][j];
                }
            }
        }
        if(midDist[n]==Integer.MAX_VALUE){
            System.out.println(-1);
        }else {
            System.out.println(midDist[n]);
        }
    }
}

Bellman_ford算法,仍然是求单源最短路径的。都是先对于上面的Dijstra来说他可以带有权值是负数的边。

Bellman_ford算法的核心思想是 对所有边进行松弛n-1次操作(n为节点数量),从而求得目标最短路

这里说一下我对松弛的理解:不断尝试通过中间路径来缩短两点间的直线距离

代码如下:

java 复制代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Bellman_ford1 {
    static class Edge{
        int from;
        int to;
        int val;
        public Edge(int from,int to,int val){
            this.from=from;
            this.to=to;
            this.val=val;
        }
    }
    public static void main(String[] args){
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        int m=scanner.nextInt();
        List<Edge> edges=new ArrayList<>();
        for(int i=0;i<m;i++){
            int from=scanner.nextInt();
            int to=scanner.nextInt();
            int val=scanner.nextInt();
            edges.add(new Edge(from,to,val));
        }
        int[] minDist=new int[n+1];
        Arrays.fill(minDist,Integer.MAX_VALUE);
        minDist[1]=0;
//        循环n-1次也就是松弛边n-1次
        for(int i=1;i<n;i++){
            for(Edge edge:edges){
//                确保from已经处理过
                if(minDist[edge.from]!=Integer.MAX_VALUE&&(minDist[edge.from]+edge.val)<minDist[edge.to]){
                    minDist[edge.to]=minDist[edge.from]+edge.val;
                }
            }
        }
        if(minDist[n]==Integer.MAX_VALUE){
            System.out.println("unconnected");
        }else{
            System.out.println(minDist[n]);
        }
    }
}

学习:代码随想录

相关推荐
云 无 心 以 出 岫2 小时前
贪心算法QwQ
数据结构·c++·算法·贪心算法
姜威鱼3 小时前
蓝桥杯python编程每日刷题 day 21
数据结构·算法·蓝桥杯
WG_174 小时前
第五章.图论
算法·图论
神里流~霜灭4 小时前
蓝桥备赛指南(12)· 省赛(构造or枚举)
c语言·数据结构·c++·算法·枚举·蓝桥·构造
双叶8365 小时前
(C语言)单链表(1.0)(单链表教程)(数据结构,指针)
c语言·开发语言·数据结构·算法·游戏
学习编程的gas5 小时前
数据结构——队列的实现
数据结构
wuqingshun3141595 小时前
蓝桥杯 切割
数据结构·c++·算法·职场和发展·蓝桥杯
JohnFF6 小时前
48. 旋转图像
数据结构·算法·leetcode
代码AC不AC7 小时前
【数据结构】队列
c语言·数据结构·学习·队列·深度讲解
小林熬夜学编程7 小时前
【高并发内存池】第八弹---脱离new的定长内存池与多线程malloc测试
c语言·开发语言·数据结构·c++·算法·哈希算法