<算法>最短路(起点到终点的最短距离)(java)

import java.util.*;


public class 最短路 {
    static Scanner sc = new Scanner(System.in) ;
    static int max = 10000 ;
    static int n ;
    static int m ;
    static int[][] e ; // e[a][b] = c 表示从a 到 b 的 距离为 c
    static int[] dis ; // 保存最短路径的长度
    static boolean[] is ; // 记录当前节点是否访问过
    static int[] p ; // 记录源点到某顶点的最短路径上的该顶点的前一个顶点(前驱)
    public static void main(String[] args) {

        System.out.println("请输入城市的个数:");
        n = sc.nextInt() ; // 节点数
        System.out.println("请输入城市之间的路线个数");
        m = sc.nextInt() ; // 给的边的连接数

        dis = new int[n + 1] ;
        is = new boolean[n + 1] ;
        p = new int[n + 1] ;
        e = new int[m + 1][m + 1] ; // e[i][j]表示i 到 j 的距离

        for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= n ; j ++){
                e[i][j] = max ;
            }
        }

        System.out.println("请输入城市之间的路线以及距离");
        for(int i = 1 ; i <= m ; i ++){
            int a = sc.nextInt() ;
            int b = sc.nextInt() ;
            int c = sc.nextInt() ;
            e[a][b] = c ;
        }


        System.out.println("请输入小明所在的位置:");
        int start = sc.nextInt() ; // 起点


        System.out.println("请输入小明要到达的位置:");
        int end = sc.nextInt() ; // 终点

        dijkstra(start);


        System.out.print("小明所在的位置:" + start + " , ");

        for(int i = 1 ; i <= n ; i ++){
            if(i == end){
                System.out.print("小明要到达的位置:" + end + " , ");
                if(dis[i] == max){
                    System.out.print("无路可达");
                }else{
                    System.out.print("最短距离为" + dis[i]);
                }
            }
        }

        find(start , end);




    }

    public static void find(int start , int end){
        int x ;
        Stack<Integer> s = new Stack<>() ;
        for(int i = 1 ; i <= n ; i ++){
            if(i == end ){
                x = p[i] ;
                while (x != start && x != -1){
                    s.push(x) ;
                    x = p[x] ;
                }
                System.out.println("最短路径为:" );
                System.out.print(start + " ");
                while (!s.isEmpty()){
                    System.out.print(s.pop() + " ");
                }
                System.out.println(end + " " );
            }

        }
    }

    private static void dijkstra(int start) {
        for(int i = 1 ; i <= n ; i ++){
            dis[i] = e[start][i] ;
            is[i] = false ;
            if( dis[i] == max  ){
                p[i] = -1 ;
            }else{
                p[i] = start ;
            }
        }

        is[start] = true ;
        dis[start] = 0 ;


        for(int i = 1 ; i <= n ; i ++){
            int temp = max ;
            int t = start ;
            for(int j = 1 ; j <= n ; j ++) {
                if (!is[j] && dis[j] < temp) {
                    t = j;
                    temp = dis[j];
                }

            }

                if(t == start){
                    return;
                }
                is[t] = true ;

                for(int j = 1 ; j <= n ; j++){
                    if( !is[j] && e[t][j] < max  ){
                        if( dis[j] > (dis[t] + e[t][j]) ){
                            dis[j] = dis[t] + e[t][j] ;
                            p[j] = t ;
                        }
                    }
                }
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值