数据结构系列内容的学习目录 → \rightarrow →浙大版数据结构学习系列内容汇总。
题目描述: 有了一张自驾旅游路线图,就会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入格式: 输入数据的第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
解题思路: ■ 城市为结点
■ 公路为边
⋄ 权重1:距离
⋄ 权重2:收费
■ 单源最短路
⋄ Dijkstra 一 距离
⋄ 等距离时按收费更新
Dijkstra算法的其他类似问题:
■ 要求数最短路径有多少条
⋄ count[s] = 1;
⋄ 如果找到更短路:count[W]=count[V];
⋄ 如果找到等长路:count[W]+=count[V];
■ 要求边数最少的最短路
⋄ count[s] = 0 ;
⋄ 如果找到更短路: count[w]=count[V]+1;
⋄ 如果找到等长路: count[w]=count[V]+1;
代码实现:
#include<iostream>
using namespace std;
#define INF 1000000
#define MaxVertex 505
typedef int Vertex;
int value[MaxVertex][MaxVertex]; //收费矩阵
int G[MaxVertex][MaxVertex]; //距离矩阵
int dist[MaxVertex]; // 距离
int cost[MaxVertex]; // 费用
bool collected[MaxVertex]; // 被收录集合
int N; // 城市的个数
int M; // 高速公路的条数
int S; // 出发地的城市编号
int D; // 目的地的城市编号
// 初始化图信息
void BuildGraph()
{
Vertex v1, v2, w1, w2;
cin >> N >> M >> S >> D; // 输入:城市的个数、高速公路的条数、出发地的城市编号、目的地的城市编号
for (Vertex i = 0; i < N; i++)
{
for (Vertex j = 0; j < N; j++)
{
G[i][j] = INF;
value[i][j] = INF;
}
cost[i] = 0;
collected[i] = false;
dist[i] = INF;
}
for (int i = 0; i < M; i++)
{
cin >> v1 >> v2 >> w1 >> w2; // 输入:城市1、城市2、高速公路长度、收费额
G[v1][v2] = w1;
G[v2][v1] = w1;
value[v1][v2] = w2;
value[v2][v1] = w2;
}
}
void Init()
{
dist[S] = 0;
collected[S] = true;
for (Vertex i = 0; i < N; i++)
if (G[S][i])
{
dist[i] = G[S][i];
cost[i] = value[S][i];
}
}
// 查找未收录顶点中dist最小者
Vertex FindMin()
{
int min = INF;
Vertex x = -1;
for (Vertex i = 0; i < N; i++)
if (S != i && !collected[i] && dist[i] < min)
{
min = dist[i];
x = i;
}
return x;
}
void Dijkstra()
{
Init();
while (1)
{
Vertex v = FindMin();
if (v == -1)
break;
collected[v] = true;
for (Vertex w = 0; w < N; w++)
{
if (!collected[w] && G[v][w])
{
if (dist[v] + G[v][w] < dist[w])
{
dist[w] = dist[v] + G[v][w];
cost[w] = cost[v] + value[v][w];
}
else if (dist[v] + G[v][w] == dist[w] && cost[v] + value[v][w] < cost[w])
{
cost[w] = cost[v] + value[v][w];
}
}
}
}
}
int main()
{
BuildGraph();
Dijkstra();
cout << dist[D] << " " << cost[D] << endl;
system("pause");
return 0;
}
测试: 输入样例的测试效果如下图所示。