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

学习:代码随想录

相关推荐
laimaxgg36 分钟前
数据结构B树的实现
开发语言·数据结构·c++·b树·算法
灋✘逞_兇2 小时前
链表的操作-反转链表
数据结构·链表
双叶8367 小时前
(C语言)虚数运算(结构体教程)(指针解法)(C语言教程)
c语言·开发语言·数据结构·c++·算法·microsoft
快来卷java9 小时前
MySQL篇(一):慢查询定位及索引、B树相关知识详解
java·数据结构·b树·mysql·adb
玉树临风ives10 小时前
leetcode 2360 图中最长的环 题解
算法·leetcode·深度优先·图论
想睡hhh10 小时前
c语言数据结构——八大排序算法实现
c语言·数据结构·排序算法
月亮被咬碎成星星12 小时前
LeetCode[15]三数之和
数据结构·算法·leetcode
JCBP_12 小时前
数据结构3
服务器·c语言·数据结构·vscode
半盏茶香12 小时前
启幕数据结构算法雅航新章,穿梭C++梦幻领域的探索之旅——堆的应用之堆排、Top-K问题
java·开发语言·数据结构·c++·python·算法·链表
小竹子1413 小时前
L1-1 天梯赛座位分配
数据结构·c++·算法