import java.util.Scanner;
/**
* 求单源点到其他各个点的最短路径及距离
* 1,定义数组map[i][j],表示i到j的距离,初始值默认为1000000.定义数组intWay[i][j],为true表示i到j的路断开。
* 2,使用迪杰斯特拉算法,定义shortest数组,表示源点到每个点的最短距离,visited表示最短距离是否求出,len表示源点到每个点所需修复的距离。path表示源点到每个点的路径
* 3,当求出一个点的最短路径时,用该点的最短路径更新剩余点的最短路径,循环直到求出所有点的最短路径为止。最后遍历得到源点到目标点的修复最短距离。
*/
public class P3905 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//点数
int N = sc.nextInt();
//边数
int M = sc.nextInt();
//无向图
int[][] map = new int[N][N];
//true标识i到j的路断裂
boolean[][] intWay = new boolean[N][N];
//初始化无向图,权值为1000000,
for(int i=0;i<N;i++) {
for(int j=0;j<N;j++) {
map[i][j] = 1000000;
}
}
//初始化连接边的权值
for(int k=0;k<M;k++) {
int i = sc.nextInt()-1;
int j = sc.nextInt()-1;
int h = sc.nextInt();
map[i][j] = h;
map[j][i] = h;
}
//断路条数
int d = sc.nextInt();
//断路
for(int k=0;k<d;k++) {
int i = sc.nextInt()-1;
int j = sc.nextInt()-1;
intWay[i][j] =true;
intWay[j][i] =true;
}
//源节点
int source = sc.nextInt()-1;
//目标节点
int target = sc.nextInt()-1;
djstl(map,intWay,source,target);
}
private static void djstl(int[][] map, boolean[][] intWay,int source,int target) {
//存放最短路径
int[] shortest = new int[map.length];
//标识该点是否求出最短路径
boolean[] visite = new boolean[map.length];
//该点需要修复的最短长度
int[] len = new int[map.length];
//输出最短路径
String[] path = new String[map.length];
//初始化输出路径
for(int i=0;i<map.length;i++) {
path[i] = new String(source+"——》"+i);
}
//初始化每个点的起始修复长度
for(int i=0;i<map.length;i++) {
if(i!=source&&map[source][i]!=200 && intWay[source][i]==true) {
len[i] += map[source][i];
}
}
shortest[source] = 0;
visite[source] = true;
for(int i=1;i<map.length;i++) {
int min = Integer.MAX_VALUE;
int index = -1;
for(int j=0;j<map.length;j++) {
if(visite[j]==false && map[source][j]<min) {
min = map[source][j];
index = j;
}
}
shortest[index] = min;
visite[index] = true;
//更新剩余点的最颠路径
for(int m=0;m<map.length;m++) {
if(visite[m]==false && map[source][index]+map[index][m]<map[source][m]) {
map[source][m] = map[source][index]+map[index][m];
map[m][source] = map[source][index]+map[index][m];
path[m] = path[index]+"——》"+m;
//计算断路距离,是断路加上,不是断路返回上一个的最短修复长度
if(intWay[index][m]==true) {
len[m] = len[index]+map[index][m];
}else {
len[m] = len[index];
}
}
}
}
//打印最短路径
// for(int i=0;i<map.length;i++) {
// if(i!=source) {
// if(shortest[i]==200) {
// System.out.println(source+1+"到"+(i+1)+",不可达");
// }else {
// System.out.println(source+1+"到"+(i+1)+"的路径是:"+path[i]+",最短距离为:"+shortest[i]+",修复道路为:"+len[i]);
// }
// }
// }
for(int i=0;i<len.length;i++) {
if(i==target) {
System.out.println(len[i]);
return;
}
}
}
}
P3905 道路重建 (迪杰斯特拉算法)
猜你喜欢
转载自blog.csdn.net/qq_28635317/article/details/113534194
今日推荐
周排行