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