题目内容
设计一个校园导游程序,为来访客人提供各种信息查询服务。测试数据根据实际情况指定。提示:一般情况下,校园的道路是双向通行的,可设校园平面图是一个无向图。顶点和边均含有相关信息。
实验要求
1设计所在学校的校园平面图,所含景点不少于10个。以图中顶点表示校内各景点,存放景点名称、代号、简介等信息;以边表示路径,存放路径长度等相关信息。
2、为来访客人提供图中任意景点相关信息的查询。
3、为来访客人提供图中任意景点的纹路查询,即查询任意两个景点之间的一条最短的简单路径。
代码
#include <iostream>
#include <vector>
#include <unordered_map>
#include <limits>
using namespace std;
// 景点结构体
struct Point {
int id;
string name;
string intro;
Point(){}
Point(int i, string n, string in) : id(i), name(n), intro(in) {}
};
// 图结构体
struct Graph {
unordered_map<int, Point> points;
unordered_map<int, unordered_map<int, int>> edges;
void addPoint(int id, string name, string intro) {
points[id] = Point(id, name, intro);
}
void addEdge(int from, int to, int weight) {
edges[from][to] = weight;
edges[to][from] = weight;
}
};
//获取景点,可以用于创建图,主函数中没有使用,根据实际需要自己调用;
void add_Node(Graph& graph) {
int n, m;
int id;
string name, intro;
int from, to, w;
cout << "请输入景点数和边数:";
cin >> n >> m;
for (int i = 0; i < n; i++) {
cout << "请输入景点的代号:";
cin >> id;
cout << "请输入景点的名称:";
cin >> name;
cout << "请输入景点的信息:";
cin >> intro;
graph.addPoint(id, name, intro);
}
for (int i = 0; i < m; i++) {
cout << "请输入路线的起点:";
cin >> from;
cout << "请输入路线的终点:";
cin >> to;
cout << "请输入路线的距离:";
cin >> w;
graph.addEdge(from, to, w);
}
}
//景点查询
void queryNodeInfo(Graph& graph) {
for(int i=0;i< graph.points.size();i++){
cout << graph.points[i].id << graph.points[i].name << endl;
}
cout << "请输入需要查询的景点代号:";
int p;
cin >> p;
cout << graph.points[p].id << "\t" << graph.points[p].name << "\t" << graph.points[p].intro << endl;
}
//查询最短路径
void dijkstra(Graph& graph, int start, int end) {
// 初始化距离和 visited 数组
unordered_map<int, int> dist;
unordered_map<int, bool> visited;
for (unordered_map<int, Point>::iterator it = graph.points.begin(); it != graph.points.end(); it++) {
dist[it->first] = numeric_limits<int>::max();
visited[it->first] = false;
}
dist[start] = 0;
// 找到距离起点最近的点
unordered_map<int, Point>::iterator minIt = graph.points.end();
for (unordered_map<int, Point>::iterator it = graph.points.begin(); it != graph.points.end(); it++) {
if (!visited[it->first] && (minIt == graph.points.end() || dist[it->first] < dist[minIt->first])) {
minIt = it;
}
}
// 更新距离数组和 visited 数组
while (minIt != graph.points.end()) {
int curr = minIt->first;
visited[curr] = true;
for (unordered_map<int, int>::iterator it = graph.edges[curr].begin(); it != graph.edges[curr].end(); it++) {
int neighbor = it->first;
int weight = it->second;
if (!visited[neighbor] && dist[curr] + weight < dist[neighbor]) {
dist[neighbor] = dist[curr] + weight;
}
}
// 找到距离起点最近的未访问点
minIt = graph.points.end();
for (unordered_map<int, Point>::iterator it = graph.points.begin(); it != graph.points.end(); it++) {
if (!visited[it->first] && (minIt == graph.points.end() || dist[it->first] < dist[minIt->first])) {
minIt = it;
}
}
}
// 输出结果
if (dist[end] == numeric_limits<int>::max()) {
cout << "不存在路径" << endl;
}
else {
vector<int> path;
int curr = end;
while (curr != start) {
path.push_back(curr);
for (unordered_map<int, int>::iterator it = graph.edges[curr].begin(); it != graph.edges[curr].end(); it++) {
int neighbor = it->first;
int weight = it->second;
if (dist[curr] == dist[neighbor] + weight) {
curr = neighbor;
break;
}
}
}
path.push_back(start);
cout << "最短路径为:";
for (vector<int>::reverse_iterator it = path.rbegin(); it != path.rend(); it++) {
cout << graph.points[*it].name << "(" << *it << ")";
if (it != path.rend() - 1) {
cout << " -> ";
}
}
cout << endl;
cout << "距离为:" << dist[end] << endl;
}
}
int main() {
// 构建图
Graph graph;
graph.addPoint(0, "图书馆", "这里是学校的图书馆");
graph.addPoint(1, "一食堂", "这里是学校的一食堂");
graph.addPoint(2, "二食堂", "这里是学校的二食堂");
graph.addPoint(3, "东区操场", "这里是学校的东区操场");
graph.addPoint(4, "教学楼2", "这里是学校的教学楼2");
graph.addPoint(5, "教学楼3", "这里是学校的教学楼3");
graph.addPoint(6, "教学楼4", "这里是学校的教学楼4");
graph.addPoint(7, "二五广场", "这里是学校的二五广场");
graph.addPoint(8, "北区宿舍", "这里是学校的北区宿舍");
graph.addPoint(9, "东区宿舍", "这里是学校的东区宿舍");
graph.addEdge(0, 1, 600);
graph.addEdge(0, 3, 500);
//graph.addEdge(0, 6, 500);
graph.addEdge(0, 7, 400);
//graph.addEdge(0, 8, 900);
graph.addEdge(1, 2, 30);
graph.addEdge(1, 6, 100);
graph.addEdge(1, 8, 50);
//graph.addEdge(2, 7, 210);
graph.addEdge(2, 6, 100);
graph.addEdge(2, 8, 40);
graph.addEdge(3, 6, 80);
graph.addEdge(3, 8, 150);
graph.addEdge(3, 9, 150);
graph.addEdge(4, 5, 50);
graph.addEdge(4, 6, 100);
graph.addEdge(4, 7, 10);
graph.addEdge(5, 6, 50);
graph.addEdge(5, 8, 150);
//graph.addEdge(6, 8, 300);
//graph.addEdge(7, 8, 250);
// 查询两点之间的最短路径
int start = 0; //默认值
int end = 5;
//菜单
int choice;
while (true) {
cout << "========== 校园导游咨询 ==========" << endl;
cout << "1. 景点查询" << endl;
cout << "2. 路径查询" << endl;
cout << "3. 开发者选项" << endl;
cout << "4. 退出" << endl;
cout << "Please enter your choice: ";
cin >> choice;
switch (choice) {
case 1:
queryNodeInfo(graph); //查询节点信息
break;
case 2:
cout << "请输入起点和终点:";
cin >> start >> end;
dijkstra(graph, start, end);
break;
case 3:
int str;
cout <<"请输入密码:" << endl;
cin >> str;
//add_Node(graph);
break;
case 4:
cout << "感谢您的使用!再见!" << endl;
return 0;
default:
cout << "Invalid choice! Please try again!" << endl;
break;
}
}
return 0;
}