P3905 道路重建 (迪杰斯特拉算法)


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;
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_28635317/article/details/113534194