数据结构与算法 · 第 2 讲:兔子与樱花:程序设计练习
数据结构与算法A 第二讲
来源:2026年9月11日课程笔记
这节课的前半段貌似什么都没讲,“貌似”二字可以去掉嘻嘻。早八来教室看论文也挺舒服的(bushi)
1. 兔子与樱花
原题参考http://cs101.openjudge.cn/practice/05443
描述
很久很久之前,森林里住着一群兔子。有一天,兔子们希望去赏樱花,但当他们到了上野公园门口却忘记了带地图。现在兔子们想求助于你来帮他们找到公园里的最短路。
输入
输入分为三个部分。
第一个部分有P+1行(P < 30),第一行为一个整数P,之后的P行表示上野公园的地点, 字符串长度不超过20。
第二个部分有Q+1行(Q < 50),第一行为一个整数Q,之后的Q行每行分别为两个字符串与一个整数,表示这两点有直线的道路,并显示二者之间的矩离(单位为米)。
第三个部分有R+1行(R < 20),第一行为一个整数R,之后的R行每行为两个字符串,表示需要求的路线。
输出
输出有R行,分别表示每个路线最短的走法。其中两个点之间,用->(矩离)->相隔。
样例输入
6
Ginza
Sensouji
Shinjukugyoen
Uenokouen
Yoyogikouen
Meijishinguu
6
Ginza Sensouji 80
Shinjukugyoen Sensouji 40
Ginza Uenokouen 35
Uenokouen Shinjukugyoen 85
Sensouji Meijishinguu 60
Meijishinguu Yoyogikouen 35
2
Uenokouen Yoyogikouen
Meijishinguu Meijishinguu样例输出
Uenokouen->(35)->Ginza->(80)->Sensouji->(60)->Meijishinguu->(35)->Yoyogikouen
Meijishinguu1.1. 直接上代码
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
using namespace std;
int main() {
int place;
cin >> place;
vector<string> destination(place);
unordered_map<string, int> id;
for (int i = 0; i < place; i++) {
cin >> destination[i];
id[destination[i]] = i;
}
// -1 表示目前没有路线
vector<vector<long long>> dist(
place, vector<long long>(place, -1)
);
// 保存两点之间的直接道路长度
vector<vector<long long>> roadLength(
place, vector<long long>(place, 0)
);
// 保存最短路径的下一个地点
vector<vector<int>> nextPlace(
place, vector<int>(place, -1)
);
for (int i = 0; i < place; i++) {
dist[i][i] = 0;
nextPlace[i][i] = i;
}
int road_num;
cin >> road_num;
for (int i = 0; i < road_num; i++) {
string start, end;
long long length;
cin >> start >> end >> length;
int u = id[start];
int v = id[end];
// 如果没有保存过这条道路,或者新道路更短
if (dist[u][v] == -1 || length < dist[u][v]) {
dist[u][v] = length;
dist[v][u] = length;
roadLength[u][v] = length;
roadLength[v][u] = length;
nextPlace[u][v] = v;
nextPlace[v][u] = u;
}
}
// Floyd 算法
for (int k = 0; k < place; k++) {
for (int i = 0; i < place; i++) {
for (int j = 0; j < place; j++) {
// i 到 k 或者 k 到 j 没有路线
if (dist[i][k] == -1 || dist[k][j] == -1) {
continue;
}
long long newDistance = dist[i][k] + dist[k][j];
if (dist[i][j] == -1 || newDistance < dist[i][j]) {
dist[i][j] = newDistance;
nextPlace[i][j] = nextPlace[i][k];
}
}
}
}
int check_num;
cin >> check_num;
for (int i = 0; i < check_num; i++) {
string start, end;
cin >> start >> end;
int current = id[start];
int target = id[end];
if (current == target) {
cout << start << '\n';
continue;
}
if (nextPlace[current][target] == -1) {
cout << "No path\n";
continue;
}
cout << destination[current];
while (current != target) {
int next = nextPlace[current][target];
cout << "->(" << roadLength[current][next] << ")->";
cout << destination[next];
current = next;
}
cout << '\n';
}
return 0;
}