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

学习:代码随想录

相关推荐
tobias.b7 小时前
计算机基础知识-数据结构
java·数据结构·考研
不想看见40410 小时前
Valid Parentheses栈和队列--力扣101算法题解笔记
开发语言·数据结构·c++
计算机安禾10 小时前
【C语言程序设计】第37篇:链表数据结构(一):单向链表的实现
c语言·开发语言·数据结构·c++·算法·链表·蓝桥杯
皮卡狮11 小时前
高阶数据结构:AVL树
数据结构·算法
不要秃头的小孩11 小时前
50. 随机数排序
数据结构·python·算法
故事和你9112 小时前
sdut-python-实验四-python序列结构(21-27)
大数据·开发语言·数据结构·python·算法
丶小鱼丶12 小时前
数据结构和算法之【栈】
java·数据结构
不要秃头的小孩13 小时前
力扣刷题——111.二叉树的最小深度
数据结构·python·算法·leetcode
散峰而望13 小时前
【基础算法】从入门到实战:递归型枚举与回溯剪枝,暴力搜索的初级优化指南
数据结构·c++·后端·算法·机器学习·github·剪枝
elseif12315 小时前
CSP-S提高级大纲
开发语言·数据结构·c++·笔记·算法·大纲·考纲