1030 Travel Plan (30分)

居安Juan發表於2020-08-16

A traveler's map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (≤500) is the number of cities (and hence the cities are numbered from 0 to N−1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format:

City1 City2 Distance Cost

where the numbers are all integers no more than 500, and are separated by a space.

Output Specification:

For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output.

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

Sample Output:

0 2 3 3 40

題目大意:

旅行者地圖上標記了兩個城市之間的距離以及花費。現在你需要寫一個程式幫助他們找到從起點城市到終點城市的最短距離,如果有多條這樣的路徑,那麼選擇花費最少的那一條,題目保證這樣的路徑只有一條。

解題思路:

Dijkstra演算法解題,在更新最短路徑的判斷條件上再加上一個花費最少的條件即可,儲存下到達每個城市的最短路徑的前驅,最後遍歷前驅並儲存到stack中輸出。

程式碼如下:

#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
int N,M,S,D,dis[510][510],cost[510][510],length[510],pay[510],pre[510];
bool visited[510];
stack<int> path;
const int MAX = 0x3f3f3f3f;
int main(){
	scanf("%d%d%d%d",&N,&M,&S,&D);
	fill(visited,visited+510,false);
	fill(dis[0],dis[0]+510*510,MAX);
	fill(cost[0],cost[0]+510*510,MAX);
	fill(length,length+510,MAX);
	fill(pay,pay+510,MAX);
	fill(pre,pre+510,-1);
	for(int i = 1 ; i <= M ; i ++){
		int a,b,diss,costt;
		scanf("%d%d%d%d",&a,&b,&diss,&costt);
		dis[a][b] = dis[b][a] = diss;
		cost[a][b] = cost[b][a] = costt;
		if(a == S)
		{
			length[b] = dis[a][b];
			pay[b] = cost[a][b];
			pre[b] = S;
		}	 
		else if(b == S)
		{
			length[a] = dis[a][b];
			pay[a] = cost[a][b];
			pre[a] = S;
		}	
	}
	visited[S] = true;
	length[S] = 0;
	pay[S] = 0;
	for(int i = 0 ; i < N ; i ++){
		int min = MAX;
		int u = -1;
		for(int j = 0 ; j < N ; j ++){
			if(!visited[j] && length[j] < min){
				min = length[j]; 
				u = j;
			}
		}
		if(u == -1)
			break;
		visited[u] = true;
		for(int j = 0 ; j < N ; j ++){
			if(!visited[j] && length[u]+dis[u][j] < length[j]){
				length[j] = length[u]+dis[u][j];
				pay[j] = pay[u] + cost[u][j];
				pre[j] = u;
			}else if(!visited[j] && length[u]+dis[u][j] == length[j] && pay[u]+cost[u][j] < pay[j]){
				pay[j] = pay[u] + cost[u][j];
				pre[j] = u;
			}
		} 
	}
	int number = D;
	while(number != -1)
	{
		path.push(number);
		number = pre[number];
	}
	while(!path.empty()){
		printf("%d ",path.top());
		path.pop();
	}
	printf("%d %d",length[D],pay[D]);
	return 0;
}

 

相關文章