数据结构与算法题目集(中文)7-9 旅游规划 (25分) (迪杰斯特拉算法)
1.题目
有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入格式:
输入说明:输入数据的第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
2.题目分析
本体就是典型的单源最短路径,使用迪杰斯特拉算法,是不过属性除了距离还有一个就是价格
3.代码
#include<iostream>
#include<queue>
using namespace std;
#define INF 100000
#define max 501
typedef struct
{
int length;
int cost;
}road;
typedef struct
{
int n, m;
road edges[max][max];
}MGraph;
int visited[11] = { 0 };
int Dijkstra(MGraph g, int v,int dist[],int costs[])
{
int s[max];
int mindis, i, j, u=-1,cost;
for (int i = 0; i < g.n; i++)
{
dist[i] = g.edges[v][i].length;
costs[i] = g.edges[v][i].cost;
s[i] = 0;
}
s[v] = 1;
dist[v] = 0;
costs[v] = 0;
for (int i = 1; i < g.n-1; i++)//运行n-1次
{
mindis = INF;
for (int j = 0; j < g.n; j++)
{
if (s[j] == 0 && dist[j] < mindis)
{
u = j;
mindis = dist[j];
cost = costs[j];
}
}
if (u == -1)return 0;
s[u] = 1;
for (int j = 0; j < g.n; j++)
{
if (s[j] == 0&&g.edges[u][j].length + mindis < dist[j])
{
dist[j] = mindis + g.edges[u][j].length;
costs[j] = cost + g.edges[u][j].cost;
}
if (s[j] == 0&&g.edges[u][j].length + mindis == dist[j] && g.edges[u][j].cost + cost < costs[j])
{
costs[j] = cost + g.edges[u][j].cost;
}
}
}
}
int main()
{
MGraph g;
int n, m, s, d;
cin >> n >>m >> s >> d;
g.n = n; g.m = m;
for (int i = 0; i < max; i++)
{
for (int j = 0; j < max; j++)
{
g.edges[i][j].length = INF;
g.edges[i][j].cost = INF;
}
}
for (int i = 0; i < m; i++)
{
int city1, city2, lon, cos;
cin >> city1 >> city2 >> lon >> cos;
g.edges[city1][city2].length = lon;
g.edges[city1][city2].cost = cos;
g.edges[city2][city1].length = lon;
g.edges[city2][city1].cost = cos;
}
int dist[max], costs[max];
if (Dijkstra(g, s, dist,costs))
{
cout << dist[d] << " " << costs[d];
}
else
cout << -1;
}