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
思路:Dijkstra算法在dis数组在保存最短路径的同时将最低收费保存下来,最后直接输出终点的距离和路费。题目保证了一定是
连通图,降低了点难度。
#include<stdio.h> #include<limits.h> #include<string.h> #include<iostream> using namespace std; #define MAXN 501 int N, M, S, D, sum, flag[MAXN]; struct Node{ int len; int money; }map[MAXN][MAXN], dis[MAXN]; void Dijkstra(int begin) { memset(flag, 0, sizeof(flag));
for (int k = 0; k < N; k++) { dis[k].len = INT_MAX; dis[k].money = INT_MAX; } dis[begin].len = 0; dis[begin].money = 0; for (int j = 0; j < N; j++) if (map[begin][j].len != -1){ dis[j].len = map[begin][j].len; dis[j].money = map[begin][j].money; } sum = 1; flag[begin] = 1; while (sum!=N){ int temp; //temp用来表示最小的那个下标 int min = INT_MAX; //用来记录当前的最小值 for (int i = 0; i < N; i++) //用来寻找最小值 if (!flag[i] && dis[i].len < min){ min = dis[i].len; temp = i; } flag[temp] = 1; //cout << "temp = " << temp << endl; sum++; for (int i = 0; i < N; i++) if (!flag[i] && map[temp][i].len != -1 && dis[temp].len + map[temp][i].len <= dis[i].len){ if (dis[temp].len + map[temp][i].len < dis[i].len) { dis[i].len = dis[temp].len + map[temp][i].len; dis[i].money = dis[temp].money + map[temp][i].money; } if (dis[temp].len + map[temp][i].len == dis[i].len) { if (dis[i].money > dis[temp].money + map[temp][i].money) dis[i].money = dis[temp].money + map[temp][i].money; } } } } int main() { cin >> N >> M >> S >> D; for (int i = 0; i < N;i++) for (int j = 0; j < N; j++) { map[i][j].len = -1; map[i][j].money = INT_MAX; } for (int i = 0; i < M; i++) { int a, b, c, d; cin >> a >> b >> c >> d; map[a][b].len = c; map[b][a].len = c; map[a][b].money = d; map[b][a].money = d; } Dijkstra(S); cout << dis[D].len << " " << dis[D].money << endl; return 0; }