旅游规划(java)

7-9 旅游规划(25 分)

有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。

输入格式:

输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。

输出格式:

在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。

输入样例:

4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

输出样例:

3 40

思路:

1、就是在Floyd算法的基础上修改一下。

2、有两个权重矩阵,最优先的是路径长度,在相同的路径长度下,再选择最便宜的价格。

3、当增加k点后路径较短时,同时更新路径权重矩阵,与价格权重矩阵。

4、回想一下在线处理的思想,当G[i][k] + G[k][j] = G[i][j]的时候,这时比较ik的价格与kj的价格之和与ij的价格。选择较小的那个更新价格矩阵。

%%%%%%%%%%%%%%%%%%%%分割线%%%%%%%%%%%%%%%%%%%%%%%

后来又听了陈越姥姥的讲解。发现自己的方法用复杂了,其实不用计算任意两点的结果,只需要计算题目给定的两个点即可,也就是单点有权最短路径问题,就是Dijstra算法的修改,当等于的时候,就只更新价格权重数组即可,思路都是一样的,不过单点的话时间复杂度是O(V^2+E),多点是O(V^3)。

注意几点Dilstra算法的几个小细节:

1、如果把原点作为没收录的第一个点,想想需不需要把图对角矩阵的对角线初始化为0,具体问题具体分析,没有统一答案。

2、从dist数组中选择未收录的最小值,注意未收录,可以直接遍历,也可以用最小堆,整体时间复杂度不一样,分别适用于稠密图和稀疏图。

3、对于V,循环的具体流程是先收录进去,然后 判断V的没有被收录进去的邻接点。更新数组。

第一个程序是Floyd算法的修改;

第二个是Dilstra算法的修改;

import java.util.Scanner;

public class Main {
	static int N;
	static int M;
	static int S;
	static int D;
	static int G[][];
	static int P[][];
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		N = in.nextInt();
		M = in.nextInt();
		S = in.nextInt();
		D = in.nextInt();
		G = new int[N][N];
		P = new int[N][N];
		int path[][] = new int[N][N];
		for(int i = 0;i<N;i++)
			for(int j = 0; j<N;j++) {
				G[i][j] = Integer.MAX_VALUE/100;
				P[i][j] = Integer.MAX_VALUE/100;
			}
		
		for(int i =0;i<M;i++) {
			int x = in.nextInt();
			int y = in.nextInt();
			G[x][y] = in.nextInt();
			G[y][x] = G[x][y];
			P[x][y] = in.nextInt();
			P[y][x] = P[x][y];
		}
		
//		for(int k = 0;k<N;k++)
//			for(int i = 0; i<N;i++)
//				for(int j = 0;j<N;j++) {
//					if(P[i][k]+P[k][j]<P[i][j])
//						P[i][j] = P[i][k]+P[k][j];
//				}
//		
//		
		for(int k = 0;k<N;k++)
			for(int i = 0; i<N;i++)
				for(int j = 0;j<N;j++) {
					if(G[i][k]+G[k][j]<G[i][j]) {
						G[i][j] = G[i][k]+G[k][j];
						P[i][j] = P[i][k]+P[k][j];
						path[i][j] = k;
					}
					else if(G[i][k]+G[k][j] == G[i][j]) {
						int tp1 = P[i][j];
						int tp2 = P[i][k]+ P[k][j];
						if(tp1>tp2) {
							path[i][j] = k;
							P[i][j] = P[i][k]+P[k][j];
						}
					}
				}
		System.out.print(G[S][D]+" "+P[S][D]);
	}

}
import java.util.Scanner;

public class Main {
	static int N;
	static int M;
	static int S;
	static int D;
	static int G[][];
	static int P[][];
	static int dist[];
	static int price[];
	static boolean collected[];
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		N = in.nextInt();
		M = in.nextInt();
		S = in.nextInt();
		D = in.nextInt();
		collected = new boolean[N];
		G = new int[N][N];
		P = new int[N][N];
		price = new int[N];
		dist = new int[N];
		for(int i =0;i<N;i++) {
			dist[i] = Integer.MAX_VALUE/10;
			price[i] = Integer.MAX_VALUE/10;
		}
		
		dist[S] = 0;
		price[S] = 0;
	
		
		for(int i =0;i<N;i++)
			for(int j =0;j<N;j++) {
				G[i][j] = Integer.MAX_VALUE/10;
				P[i][j] = Integer.MAX_VALUE/10;
				if(j==i) {
					G[i][j] = 0;
					P[i][j] = 0;
				}
			}
		
		for(int i =0;i<M;i++) {
			int x = in.nextInt();
			int y = in.nextInt();
			G[x][y] = in.nextInt();
			G[y][x] = G[x][y];
			P[x][y] = in.nextInt();
			P[y][x] = P[x][y];
		}
		
		while(true) {
			int V = min_dist();
			
			if(V == -1)
				break;
			collected[V] = true;
			for(int W = 0;W<N;W++) {
				if(G[V][W]<Integer.MAX_VALUE/10&&collected[W]==false)
				{
					
					if(dist[W]>G[V][W]+dist[V]) {
						dist[W] = dist[V]+G[V][W];
						price[W] = price[V]+P[V][W];
					}
					else if(dist[W]==G[V][W]+dist[V]) {
						if(price[V]+P[V][W]<price[W]) {
							price[W] = price[V]+P[V][W];
						}
					}
				}
			}
		}
		System.out.print(dist[D]+" "+price[D]);
	}
	private static int min_dist() {
		// TODO Auto-generated method stub
		int temp = Integer.MAX_VALUE/10;
		int count = -1;
		for(int i = 0;i<N;i++) {
			if(dist[i]<temp&&collected[i]==false) {
				temp = dist[i];
				count = i;
			}
		}
		return count;
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_38902950/article/details/81179039
今日推荐