图——Dijstra算法——求解最短路径

本算法的主要思想是:

  1. 每一次找出源节点到各节点的路径长,取出其中最短的一个,此时到达该节点没有其他最短路径了,然后做上标记,防止下一次访问。
  2. 找到该路径以后,再更新通过当前节点跳往其他节点的路径,但不标记。
  3. 直到找到所有最短路径长。
package graph.DijstraAlgorithm;

import java.util.Scanner;

public class DijstraAlgorithm {
   public static int Max_Value = 100000;//不能设置为Integer的最大值,防止数组越界

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入图的顶点数和边数:");
        int vertex = scanner.nextInt();
        int edge = scanner.nextInt();

        int[][] martix = new int[vertex][vertex];

        //初始化图的关系矩阵
        for (int i = 0; i < vertex; i++) {
            for (int j = 0; j < vertex; j++) {
                martix[i][j] = Max_Value;
            }
        }
        //配置相应的边信息
        for (int i = 0; i < edge; i++) {
            System.out.println("第"+(i+1)+"条边及其权值:");
            int source = scanner.nextInt();
            int target = scanner.nextInt();
            int weight = scanner.nextInt();
            martix[source][target] = weight;
        }

        System.out.println("请输入出发点的序号(此序号应该大于0,小于"+vertex+":");
        int source = scanner.nextInt();
        dijstra(source,martix);

    }

    private static void dijstra(int source, int[][] martix) {
        //最短路径集合
        int[] shortest = new int[martix.length];
        //标记已经找到最短路径
        int[] visited = new int[martix.length];
        //记录到达各节点最短路径的路径长度
        String[] path = new String[martix.length];
        for (int i = 0; i < martix.length; i++) {
            path[i] = new String(source+"->"+i);
        }

        for (int i = 1; i < martix.length; i++) {
            int min = Integer.MAX_VALUE;
            int index = -1;

            for (int j = 0; j < martix.length; j++) {
                if(visited[j]==0&&martix[source][j]<min){
                    min = martix[source][j];
                    index = j;
                }
            }

            //更新到本次遍历过程中的最短路径
            visited[index] = 1;
            shortest[index] = min;

            //更新通过index节点到达其他节点的路径长度
            for (int j = 0; j < martix.length; j++) {
                if (visited[j]==0&&martix[source][index]+martix[index][j]<martix[source][j]){
                    martix[source][j] = martix[source][index]+martix[index][j];
                    path[j] = path[index]+"->"+j;
                }
            }
        }

        for (int i = 0; i < path.length; i++) {
            if (i!=source){
                if(shortest[i]<Max_Value){
                    System.out.println(source+"->"+i+"的路径为:"+path[i]);
                }else {
                    System.out.println(source+"不能达到"+i);
                }
            }
        }
    }
}
  1. Dijstra算法不支持负权值,因为每一次找到一条最短路径,都会进行标记并且不再修改其值,但是当出现负值时,可能会导致原有的最短路径并不是真正的最短路径,但此时已经对该最短路径进行了标记,无法修改。
  2. 本算法中使用的节点关系初始化权值为Max_Value,而不是Integer的最大值,是因为计算节点的最短路径时会进行相加,若采用后者则会溢出。
  3. Dijstra算法适合于求单点最短路径。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值