2020/11/03 朴素迪杰斯特拉

朴素迪杰斯特拉算法

题目

给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值。
请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1。

输入格式
第一行包含整数n和m。
接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。

输出格式
输出一个整数,表示1号点到n号点的最短距离。
如果路径不存在,则输出-1。

数据范围
1≤n≤500,
1≤m≤105,
图中涉及边长均不超过10000。

输入样例:
3 3
1 2 2
2 3 1
1 3 4
输出样例:
3

思路分析

朴素迪杰斯特拉算法适用于求没有负边的最短路径,具体流程很简单,只有三步(+初始化)

  • 初始化: 初始化图的边的信息为无穷,同时初始化源节点的距离为0
  • 正式算法:(进行n次迭代,一次解决一个节点)
  1. 找到集合外距离源点最短距离的节点
  2. 将此节点加入集合中
  3. 更新所有的节点距离(因为集合内的节点就是最终结果了,所以可以直接跳过集合内的结点,只更新集合外的节点距离)

定义变量

此算法必须要定义的变量:

  • st[] 用于存储确定集合
  • INF用于存储不相连的边的权值

邻接矩阵需要定义的变量:

  • g[][]:用于存储两节点间边的信息

  • dis[]:用于存储节点到源的距离信息

    初始化时定义源节点距离为0dis[1]=0,其余均为INF

源代码

import java.util.*;
class Main{
    static int N=510;
    static int[][] g=new int[N][N];
    static int[] dis=new int[N];
    static boolean[] st=new boolean[N];
    static int n;
    static int m;
    static int INF=0x3f3f3f;
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        m=sc.nextInt();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                g[i][j]=INF;
            }
        }
        Arrays.fill(dis,INF);
        while(m-->0){
            int x=sc.nextInt();
            int y=sc.nextInt();
            int z=sc.nextInt();
            g[x][y]=Math.min(g[x][y],z);
        }
        System.out.print(djs());
    }
    public static int djs(){
        dis[1]=0;
        for(int i=0;i<n;i++){
            int t=-1;
            for(int j=1;j<=n;j++){
                if((t==-1||dis[j]<dis[t])&&(!st[j])){
                    t=j;
                }
            }
            st[t]=true;
            for(int j=1;j<=n;j++){
                if(!st[j]){
                    dis[j]=Math.min(dis[j],dis[t]+g[t][j]);
                }
            }
        }
        if(dis[n]==INF) return -1;
        return dis[n];
    }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值