这类问题比较集中 基本上是“n座城市,有m条路,路有起点、终点、长度等属性,求从X到Y”这种问题的变形。我们一般采用迪杰斯特拉算法或Floyd算法来解决问题。
- 迪杰斯特拉算法
这里,我们就以典型例子为例来解答,请看代码:
import java.util.Scanner;
public class 迪杰斯 {
public static void main(String[] args){
Scanner s = new Scanner(System.in);
int n,r;
n = s.nextInt();//城市总数
r = s.nextInt();//道路总数
int path[][]=new int[n+1][n+1];//从某点到某点的值
for(int i=1;i<n+1;i++){
for(int j=1;j<n+1;j++)
path[i][j]=Integer.MAX_VALUE;//取最大值
}
for(int i = 0;i<r;i++){
int f = s.nextInt();//出发点
int d = s.nextInt();//到达点
path[f][d] = s.nextInt();//长度
}
int minLen[]=new int[n+1];//从1到X点的距离
int visit[]=new int[n+1];//经过的点
for(int i=1;i<n+1;i++){
minLen[i]=path[1][i];
}
minLen[1]=0;//自己到自己当然是零
visit[1]=1;//已被经过的点被置为1
int minj=1;
for(int i=1;i<n+1;i++){
int min=Integer.MAX_VALUE;
for(int j=1;j<n+1;j++){
if(visit[j]==0&&minLen[j]<min){
//j没有经过 且当有路径可取J 且J比之前的值小时 既取最短的路
min=minLen[j];
minj=j;
}
}
visit[minj]=1;//既上面的j 点已经过
for(int j=1;j<n+1;j++){
if(visit[j]==0&&//没有经过的为0
minLen[minj]!=Integer.MAX_VALUE&&//到minj有值时
path[minj][j]!=Integer.MAX_VALUE&&//minj到j有值时
minLen[j]>(minLen[minj]+path[minj][j])){
//路线为(1,minj,j)小于之前到j的数值
minLen[j]=minLen[minj]+path[minj][j];//替换
}
}
}
System.out.println(minLen[想要的答案]); //打印想要的答案即可
}
}
我们就是这样一层一层的得到想要的答案的,这里求得是从第一个点到别的各个点的最短距离。
- Floyd算法
也叫插点法,额,边做边学才能学的更快,来,我们看道题。
例题
这道题里有个烟雾弹。我们更应该关注的是他的钱数,既这里的钱代替了例题里的长度的地位。我是这么写的。
import java.util.Scanner;
public class Bob和他的女朋友 {
public static void main(String[] args){
Scanner s = new Scanner(System.in);
int m,n,r;
m = s.nextInt();//钱的总数
n = s.nextInt();//城市总数
r = s.nextInt();//道路总数
int a[][] = new int[n+1][n+1];
int b[][] = new int[n+1][n+1];
for(int i=1;i<(n+1);i++){
for(int j=1;j<(n+1);j++){
b[i][j]=10000;//把B值设为极大值
}
}
for(int i = 0;i<r;i++){
int f = s.nextInt();//出发点
int d = s.nextInt();//到达点
a[f][d] = s.nextInt();//长度
b[f][d] = s.nextInt();//money
}
for(int j=1;j<(n+1);j++){//中间值一定要在最外面
for(int i=1;i<(n+1);i++){//起点
for(int k=1;k<(n+1);k++){//终点
if(b[i][j]+b[j][k]<b[i][k]){
b[i][k]=b[i][j]+b[j][k];
a[i][k]=a[i][j]+a[j][k];
}
}
}
}
int max = n;
System.out.println(a[1][max]);//为0 floyd默认没有连接的路取无限大值
}
}
这就是Floyd算法,他可以直接得出你想要的起点终点间的最短距离,但相应的时间复杂度也更高,更耗时间。两方法各有千秋。