力扣.1976.到达目的地的方安数

文章介绍了如何使用Dijkstra算法在给定的矩阵图中找到起始节点到所有其他节点的最短路径,并计算每条路径的数量。算法通过构建辅助数组和遍历节点更新最短路径和路径数量。
摘要由CSDN通过智能技术生成

借用题目给的例子

1.构建矩阵

int[][] roads = {
                {0, 6, 7},
                {0, 1, 2},
                {1, 2, 3},
                {1, 3, 3},
                {6, 3, 3},
                {3, 5, 1},
                {6, 5, 1},
                {2, 5, 1},
                {0, 4, 5},
                {4, 6, 2}
        };


        int n=7;
        int [][] neighbor = new int[n][n];
        for(int[] element : neighbor)
        {
            Arrays.fill(element,Integer.MAX_VALUE/2);//int.MAX_VALUE/2 防止运算过程中 数据溢出
        }


        for(int[] row : roads)
        {
            int x = row[0];
            int y = row[1];
            int m = row[2];
            neighbor[x][y]=m;
            neighbor[y][x]=m;
        }

2.思路

  根据dis算法,我们先求以 起始节点到每个节点的最短距离 为基准,建立辅助数组来统计到这个节点的最短距离的路径条数;

long [] dis = new long[n]; //到达该节点的最短路径距离
        boolean[] done = new boolean[n];//该节点是否被走过
        int[] res = new int[n]; //到达该节点的最短路径的条数
        res[0]=1;
        Arrays.fill(dis,1,n,Long.MAX_VALUE/2);
        dis[0]=0;
        long  min = dis[0];
        int y=0;
        int k = n;

   每当走到一个新的结点时,判断   当前节点到新节点的距离 与 初始节点到当前节点的最短距离之和是否小于等于 已记录的初始节点到新节点 的最短距离,判断是否需要更改;如果需要更改:

两种情况
   1.相等时:初始节点到新节点最短路径数量更新为  记录的初始节点到新节点 的路径条数 加上 初始节点到当前节点的最短距离路径条数;

    2.小于:  初始节点到新节点最短路径数量更新为  初始节点到当前节点的最短距离路径条数;

while(k>0)
        {
            for(int i=0;i<n;i++)//找现有节点中最短的节点
            {
                if(dis[i]<=min && done[i]==false)
                {
                    min = dis[i];
                    y=i;

                }
                // done[y]=true;
            }
            min = Long.MAX_VALUE;
            done[y]=true;
            for(int j=0;j<n;j++)//走当前节点连接的节点
            {
                if((neighbor[y][j]+dis[y])<=dis[j])//可更新 新的 最短路径
                {
                    if( dis[j]==(neighbor[y][j]+dis[y]))//相等 最短路径 数加一
                    {
                        res[j]=(res[y]+res[j]) % 1_000_000_007;
                    }else if ( dis[j]>(neighbor[y][j]+dis[y])){//小于 更新最短路径数为上一个节点的最短路径
                        res[j]=res[y];
                    }
                    dis[j]=neighbor[y][j]+dis[y];//更新最短路径距离
                }
            }
            k--;

        }

        System.out.println(res[n-1]);

3.总代码

package com.yyxxlu;

import java.util.Arrays;

public class 到达目的地的方安数1976 {
    public static void main(String[] args){

        int[][] roads = {
                {0, 6, 7},
                {0, 1, 2},
                {1, 2, 3},
                {1, 3, 3},
                {6, 3, 3},
                {3, 5, 1},
                {6, 5, 1},
                {2, 5, 1},
                {0, 4, 5},
                {4, 6, 2}
        };


        int n=7;
        int [][] neighbor = new int[n][n];
        for(int[] element : neighbor)
        {
            Arrays.fill(element,Integer.MAX_VALUE/2);//int.MAX_VALUE/2 防止运算过程中 数据溢出
        }


        for(int[] row : roads)
        {
            int x = row[0];
            int y = row[1];
            int m = row[2];
            neighbor[x][y]=m;
            neighbor[y][x]=m;
        }

        long [] dis = new long[n]; //到达该节点的最短路径距离
        boolean[] done = new boolean[n];//该节点是否被走过
        int[] res = new int[n]; //到达该节点的最短路径的条数
        res[0]=1;
        Arrays.fill(dis,1,n,Long.MAX_VALUE/2);
        dis[0]=0;
        long  min = dis[0];
        int y=0;
        int k = n;
        while(k>0)
        {
            for(int i=0;i<n;i++)//找现有节点中最短的节点
            {
                if(dis[i]<=min && done[i]==false)
                {
                    min = dis[i];
                    y=i;

                }
                // done[y]=true;
            }
            min = Long.MAX_VALUE;
            done[y]=true;
            for(int j=0;j<n;j++)//走当前节点连接的节点
            {
                if((neighbor[y][j]+dis[y])<=dis[j])//可更新 新的 最短路径
                {
                    if( dis[j]==(neighbor[y][j]+dis[y]))//相等 最短路径 数加一
                    {
                        res[j]=(res[y]+res[j]) % 1_000_000_007;
                    }else if ( dis[j]>(neighbor[y][j]+dis[y])){//小于 更新最短路径数为上一个节点的最短路径
                        res[j]=res[y];
                    }
                    dis[j]=neighbor[y][j]+dis[y];//更新最短路径距离
                }
            }
            k--;

        }

        System.out.println(res[n-1]);
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值