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]);
        }
    }
}

学习:代码随想录

相关推荐
秋凉 づᐇ44 分钟前
2024-11-16 串的存储结构
数据结构
丫头,冲鸭!!!1 小时前
内部排序和外部排序以及常见算法和时间复杂度
数据结构·算法·排序算法
Dola_Pan1 小时前
十大经典排序算法-希尔排序与归并排序
数据结构·算法·排序算法
未知陨落2 小时前
数据结构——AVL树
开发语言·数据结构·c++·avl树
誓约酱2 小时前
排序算法 -计数排序
数据结构·c++·算法·排序算法
Fms_Sa2 小时前
分别写出在散列表中插入和删除关键字为K的一个记录的算法,设散列函数为H,解决冲突的方法为链地址法。
c语言·数据结构·算法·哈希算法·散列表
秋凉 づᐇ6 小时前
2024-11-16 串的定义和基本操作
数据结构
励志成为嵌入式工程师6 小时前
数据结构(单向链表——c语言实现)
c语言·数据结构·链表
阿七想学习6 小时前
数据结构《栈和队列》
java·开发语言·数据结构