dijsktra算法之旅游规划(距离+花费)

题意

以城市为结点,公路为边,每条公路有两个权重:距离、收费,计算某两点间的最优路径。(最优定义为:距离最短,若距离相等则取收费最少的路径)
Sample Input:
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
输入的第一行为:城市数 公里数 起点 终点
下面每行:城市1 城市2 距离 收费

解题关键

这是一条典型的dijkstra单源最短路径问题,只是“最短”的度量扩张到了两个维度“距离、收费”,相应的在更新最短路径时有两种情况要考虑:
① 比原路径长度更短,则更新
② 与原路径长度相等,但收费更少,则更新

代码

	public static void main(String[] args) {
		
		Scanner in = new Scanner(System.in);
		int nCity = in.nextInt(), nRoute = in.nextInt();
		int[][][] G = new int[nCity][nCity][2];
		int start = in.nextInt(), end = in.nextInt();
		//初始化图
		for(int i=0; i<nCity; i++){
			for(int j=0; j<nCity; j++){
				G[i][j][0] = Integer.MAX_VALUE;
				G[i][j][1] = Integer.MAX_VALUE;
			}
			G[i][i][0] = 0;
			G[i][i][1] = 0;
		}
		//插入边
		while(nRoute--!=0){
			int i = in.nextInt(), j = in.nextInt();
			int dist = in.nextInt();
			int cost = in.nextInt();
			G[i][j][0] = dist;
			G[i][j][1] = cost;
			G[j][i][0] = dist;
			G[j][i][1] = cost;
		}
		
		//dijkstra
		int[] dist = new int[nCity];	//距离
		int[] cost = new int[nCity];	//收费
		int[] path = new int[nCity];	//路径
		path[start] = -1;	//起点没有前驱
		boolean[] visited = new boolean[nCity];		//判断是否已经加入已访问的顶点集
		Arrays.fill(visited, false);
		visited[start] = true;	//起点默认已访问
		for(int i=0; i<nCity; i++){		//初始化距离和收费
			dist[i] = G[start][i][0];
			cost[i] = G[start][i][1];
		}
		while(true){
			//找最小距离
			int minDistIndex = -1, minDist = Integer.MAX_VALUE;
			for(int i=1; i<nCity; i++){
				if(!visited[i]&&dist[i]<minDist){
					minDist = dist[i];
					minDistIndex = i;
				}
			}
			if(minDistIndex==-1){	//找不到未访问最小距离,即全走完
				break;
			}
			visited[minDistIndex] = true;	//加入已访问的顶点集
			//更新最短距离
			for(int j=0; j<nCity; j++){
				if(j!=minDistIndex&&G[minDistIndex][j][0]!=Integer.MAX_VALUE){	//找出每一个邻接点
					if(dist[minDistIndex]+G[minDistIndex][j][0]<dist[j]&&!visited[j]){	//①比原路径长度更短
						dist[j] = dist[minDistIndex]+G[minDistIndex][j][0];		//更新距离
						cost[j] = cost[minDistIndex]+G[minDistIndex][j][1];		//更新收费
						path[j] = minDistIndex;		//记录路径
					}else if(dist[minDistIndex]+G[minDistIndex][j][0]==dist[j]&&!visited[j]&&cost[minDistIndex]+G[minDistIndex][j][1]<cost[j]){	//②与原路径长度相等,但收费更少
						cost[j] = cost[minDistIndex]+G[minDistIndex][j][1];		//更新收费(距离相等不用更新)
						path[j] = minDistIndex;		//记录路径
					}
				}
			}
		}
		
		//利用栈逆序路径,输出
		Stack<Integer> stack = new Stack<>();
		int index = end;
		while(index!=-1){
			stack.push(index);
			index = path[index];
		}
		while(!stack.isEmpty()){
			System.out.print(stack.pop()+",");
		}
	}

你可能感兴趣的:(dijsktra算法之旅游规划(距离+花费))