Keywords: dij weight on edge
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:
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
Note:
- 题意
- 注意费时一小时,题目很简单但是第一遍读题不仔细,以为输出的是dij经过的节点个数,其实是路径长度(两者恰巧相等)
- debug时看到网上他人代码有输入边查重,可以考虑,以防变态数据
Code1
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
const int MAX = 1e4 ;
int sum_cost[MAX], cost[MAX][MAX], path[MAX];
int collected[MAX] = {0},a[MAX][MAX], distances[MAX], num;
void Dijkstra(int start){
collected[start] = 1;
while(1){
int min = MAX, ptr;
for(int i = 0;i < num; i++){
if(collected[i] == 0 && distances[i] < min){
min = distances[i];
ptr = i;
}
}
if(min == MAX) break;
collected[ptr] = 1;
for(int i = 0; i < num; i++){
if(collected[i] == 0 && a[ptr][i] + distances[ptr] < distances[i]){
sum_cost[i] = sum_cost[ptr] + cost[ptr][i];
distances[i] = a[ptr][i] + distances[ptr];
path[i] = ptr;
}
else if(collected[i] == 0 && a[ptr][i] + distances[ptr] == distances[i]){
if(sum_cost[ptr] + cost[ptr][i] < sum_cost[i]){
sum_cost[i] = sum_cost[ptr] + cost[ptr][i];
path[i] = ptr;
}
}
}
}
}
int main(){
int start, des, edge;
#ifdef _DEBUG
ifstream cin("data.txt");
#endif
cin >> num >> edge >> start >> des;
fill(a[0], a[0] + MAX * ( num), MAX);
fill(distances, distances + num, MAX);
fill(cost[0], cost[0] + MAX * (num), MAX);
for(int i = 0; i < edge; i++){
int tempa, tempb, tempc, tempd;
cin >> tempa >> tempb >> tempc >> tempd;
if(a[tempa][tempb] > tempc) { //当有重边时,更新相关信息
a[tempa][tempb] = tempc;
a[tempb][tempa] = tempc;
cost[tempa][tempb] = tempd;
cost[tempb][tempa] = tempd;
}
if(a[tempa][tempb] == tempc && tempd<cost[tempa][tempb]) {
a[tempa][tempb] = tempc;
a[tempb][tempa] = tempc;
cost[tempa][tempb] = tempd;
cost[tempb][tempa] = tempd;
}
}
for(int i = 0; i < num; i++){
if(a[start][i] < MAX){
distances[i] = a[start][i];
path[i] = start;
sum_cost[i] = cost[start][i];
}
}
path[start] = -1;
Dijkstra(start );
int temp =path[des], cnt = 0, real_path[MAX], min_dis = a[des][temp];
while(temp != -1){
if(path[temp] > -1)
min_dis += a[temp][path[temp]];
real_path[cnt++] = temp;
temp = path[temp];
}
for(int i = cnt - 1; i >= 0; i--){
cout << real_path[i] << " ";
}
cout << des << " " << min_dis << " " << sum_cost[des];
#ifdef _DUBUG
cin.close();
#endif
return 0;
}