借用题目给的例子
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]);
}
}