// 校园导航系统
#include <bits/stdc++.h>
#include <windows.h>
using namespace std;
#define INF 100000 // 无穷
int k; // 景点个数
typedef struct
{
int num; // 编号
char name[10]; // 名称
char message[300]; // 信息
} sight; // 景点
typedef struct
{
sight si[101]; // 景点
int edges[101][101]; // 邻接矩阵
int vertex_num, edge_num; // 点数和边数
} Campus;
void Get_campus(Campus &c); // 读取文件信息创建校园图
void Display_menu(); // 显示主页面
int Select_choice(Campus &c); // 选择要实现的功能
void Print_campus(); // 打印校园地图
int Check_choice(string &s); // 判断输入的景点编号是否合法
void Search_sightdata(Campus &c); // 校园景点信息查询
void Floyd_shortpath(Campus &c); // 求两景点间最短路径
void Achieve_shortpath(Campus &c, int st, int en); // 打印两点间最短路径(无输入)
void Print_shortpath(Campus &c); // 打印两景点间最短路径
void DFS_allpath(Campus &c, int st, int en); // 求两景点间所有路径
void Print_allpath(Campus &c); // 打印两景点间所有路径
void Amount_bestpath(Campus &c); // 求多景点间最佳访问路线
void Display_menu()
{
cout << "\t\t┌──────────────────────── 郑州大学校园景点导航系统 ────────────────────────┐" << endl;
cout << "\t\t│ │" << endl;
cout << "\t\t│ │" << endl;
cout << "\t\t│ ┌────────────────────────────┐ ┌────────────────────────────┐ │" << endl;
cout << "\t\t│ │ 1.校园景点地图一览 │ │ 2.校园景点信息查询 │ │" << endl;
cout << "\t\t│ └────────────────────────────┘ └────────────────────────────┘ │" << endl;
cout << "\t\t│ │" << endl;
cout << "\t\t│ ┌────────────────────────────┐ ┌────────────────────────────┐ │" << endl;
cout << "\t\t│ │ 3.两景点间最短路径查询 │ │ 4.两景点间所有路径查询 │ │" << endl;
cout << "\t\t│ └────────────────────────────┘ └────────────────────────────┘ │" << endl;
cout << "\t\t│ │" << endl;
cout << "\t\t│ ┌────────────────────────────┐ ┌────────────────────────────┐ │" << endl;
cout << "\t\t│ │ 5.多景点间访问路线查询 │ │ 6.退出校园景点导航系统 │ │" << endl;
cout << "\t\t│ └────────────────────────────┘ └────────────────────────────┘ │" << endl;
cout << "\t\t│ │" << endl;
cout << "\t\t└──────────────────────────────────────────────────────────────────────────┘" << endl
<< endl;
cout << "-->请选择下一步你要进行的操作" << endl;
}
int Check_choice(string &s) // 增强程序的健壮性
{
while (1)
{
int choice;
int num = 0;
int flag = 1;
for (int i = 0; i < s.length(); i++) // 将字符串转化为数字
if (s[i] < '0' && s[i] > '9')
{
flag = 0;
cout << "请输入数字!" << endl;
break;
}
else
{
num = num * 10 + s[i] - '0';
}
if (flag)
{
if (num < 0 || num > k)
{
cout << "输入不合法,请选择数字1~" << k << "输入!" << endl;
cin >> s;
}
else
return num;
}
}
}
int Select_choice(Campus &c)
{
string choice;
while (1)
{
cin >> choice;
int num = 0;
int flag = 1;
for (int i = choice.length() - 1; i >= 0; i--)
if (choice[i] < '0' && choice[i] > '9')
{
flag = 0;
cout << "请输入正确的操作编号:" << endl;
break;
}
else
{
num = num * 10 + choice[i] - '0';
}
if (flag)
switch (num)
{
case 1: // 打印校园地图
system("cls");
Display_menu();
Print_campus();
cout << "-->请选择下一步你要进行的操作" << endl;
break;
case 2: // 景点信息查询
system("cls");
Display_menu();
Search_sightdata(c);
cout << "-->请选择下一步你要进行的操作" << endl;
break;
case 3: // 两点间最短路径
system("cls");
Display_menu();
Print_shortpath(c);
cout << "-->请选择下一步你要进行的操作" << endl;
break;
case 4: // 两点间所有路径
system("cls");
Display_menu();
Print_allpath(c);
cout << "-->请选择下一步你要进行的操作" << endl;
break;
case 5: // 多景点间最佳路径
system("cls");
Display_menu();
Amount_bestpath(c);
cout << "-->请选择下一步你要进行的操作" << endl;
break;
case 6: // 退出系统
system("cls");
cout << "程序将在5秒内关闭";
Sleep(5000);
exit(0);
default:
cout << "请输入正确的操作编号:" << endl;
}
}
}
void Get_campus(Campus &c)
{
FILE *f;
f = fopen("E:\\vscode\\design\\mapabcdefg.txt", "r");
if (!f)
{
cout << "文件无法打开,初始化失败,请检查文件" << endl;
Sleep(5000);
exit(1);
}
else
{
fscanf(f, "%d%d", &c.vertex_num, &c.edge_num); // 读取点数和边数
k = c.vertex_num;
for (int i = 1; i <= c.vertex_num; i++)
{
fscanf(f, "%d%s%s", &c.si[i].num, &c.si[i].name, &c.si[i].message); // 读取景点信息
for (int j = 1; j <= c.vertex_num; j++) // 初始化邻接矩阵
{
if (i == j)
c.edges[i][j] = 0;
else
c.edges[i][j] = INF;
}
}
for (int t = 0; t < c.edge_num; t++) // 完善邻接矩阵
{
int i, j, len;
fscanf(f, "%d%d%d", &i, &j, &len);
c.edges[i][j] = c.edges[j][i] = len;
}
}
fclose(f);
}
void Print_campus()
{
cout << "\t\t\t ┌─── 北 体 ──────────────────────────────────┐" << endl;
cout << "\t\t\t │ 1) │" << endl;
cout << "\t\t\t │ 操 场 │" << endl;
cout << "\t\t\t │ \\ │" << endl;
cout << "\t\t\t │ \\ │" << endl;
cout << "\t\t\t │ 厚 │" << endl;
cout << "\t\t\t │───────────── 3) ─────────────────────────────│" << endl;
cout << "\t\t\t │ 山 │" << endl;
cout << "\t\t\t │ │ │" << endl;
cout << "\t\t\t │ │ │" << endl;
cout << "\t\t\t │ 本源 眉 钟 图 启 明 │" << endl;
cout << "\t\t\t │─ 2) ─── 6) ─ 4) ─ 5) 书 ─ 10) ─│" << endl;
cout << "\t\t\t │ 体育场 湖 楼 馆 广 场 │" << endl;
cout << "\t\t\t │ │ │" << endl;
cout << "\t\t\t │ │ │" << endl;
cout << "\t\t\t │ 7) 松 林 │" << endl;
cout << "\t\t\t │ │ │" << endl;
cout << "\t\t\t │ 8) 樱 花 林 │" << endl;
cout << "\t\t\t │ │ │" << endl;
cout << "\t\t\t │ ┌─── 12) 校 史 馆 ─────────────────────────│" << endl;
cout << "\t\t\t │ │ │ │" << endl;
cout << "\t\t\t └─ 9)南 操─── 11)五星广场─────────────────────────┘" << endl;
}
void Search_sightdata(Campus &c)
{
Print_campus();
cout << "-->请输入你所要查询景点的编号" << endl;
string i;
cin >> i;
int j;
j = Check_choice(i);
cout << "此景点信息如下:" << endl;
cout << "景点编号:" << c.si[j].num << endl;
cout << "景点名称:" << c.si[j].name << endl;
cout << "景点介绍:" << c.si[j].message << endl;
}
int dist[101][101]; // 路径距离
int path[101][101]; // 路径中继点
void Floyd_shortpath(Campus &c) // 利用弗洛伊德算法求出两点间最短路径
{
for (int i = 1; i <= c.vertex_num; i++)
for (int j = 1; j <= c.vertex_num; j++)
{
dist[i][j] = c.edges[i][j];
if (i != j && dist[i][j] < INF)
path[i][j] = i; // 表明i和j相邻
else
path[i][j] = -1; // 表明无法直接到达j
}
for (int t = 1; t <= c.vertex_num; t++)
for (int i = 1; i <= c.vertex_num; i++)
for (int j = 1; j <= c.vertex_num; j++)
{
if (dist[i][j] > (dist[i][t] + dist[t][j]))
{
dist[i][j] = dist[i][t] + dist[t][j];
path[i][j] = t; // 表面i可通过t点最短到达j
}
}
}
void Achieve_shortpath(Campus &c, int st, int en) // 打印两点间最短路径(无输入)
{
if (path[st][en] == st)
return;
else
{
Achieve_shortpath(c, st, path[st][en]); // 将中间点作为终点继续打印路径
cout << c.si[path[st][en]].name << "->"; // 打印中间景点名字
Achieve_shortpath(c, path[st][en], en); // 将中间点作为起点继续打印路径
}
}
void Print_shortpath(Campus &c) // 打印两点间最短路径(附输入)
{
Print_campus();
string st1, en1;
int st, en;
cout << "请输入起点编号" << endl;
cin >> st1;
st = Check_choice(st1);
cout << "请输入终点编号" << endl;
cin >> en1;
en = Check_choice(en1);
cout << c.si[st].name << "->";
Achieve_shortpath(c, st, en);
cout << c.si[en].name << endl;
cout << "路径总长度为:" << dist[st][en] << "米" << endl;
}
vector<int> road; // 路径
int num; // 路径个数
int visited[101]; // 是否访问
void DFS_allpath(Campus &c, int st, int en)
{
int kilo = 0;
road.push_back(st);
visited[st] = 1;
for (int i = 1; i <= c.vertex_num; i++) // 遍历所有点
{
if (c.edges[st][i] != 0 && c.edges[st][i] != INF && !visited[i]) // 找出可到达且不是本身且未访问过的点
{
if (i == en) // 到达终点
{
cout << "第" << num << "条路:";
num++;
for (int j = 0; j < road.size(); j++)
{
cout << c.si[road[j]].name << "->";
if (j < road.size() - 1)
kilo += c.edges[road[j]][road[j + 1]];
}
kilo += c.edges[road[road.size() - 1]][i];
cout << c.si[en].name;
cout << "\t路径总长度为" << kilo << "米" << endl;
}
else
{
DFS_allpath(c, i, en);
road.pop_back();
visited[i] = 0;
}
}
}
}
void Print_allpath(Campus &c)
{
Print_campus();
string st1, en1;
int st, en;
num = 1;
road.clear();
for (int i = 0; i < k + 1; i++)
visited[i] = 0;
cout << "请输入起点编号" << endl;
cin >> st1;
st = Check_choice(st1);
cout << "请输入终点编号" << endl;
cin >> en1;
en = Check_choice(en1);
DFS_allpath(c, st, en);
}
void Amount_bestpath(Campus &c)
{
Print_campus();
int kilo = 0, temp = 1;
vector<int> visit;
do
{
cout << "请输入你想游览的第" << temp << "个景点的编号(输入0结束):" << endl;
string i;
cin >> i;
if (i == "0")
break;
else
{
int j;
j = Check_choice(i);
visit.push_back(j);
temp++;
}
} while (1);
if (temp == 1)
return;
cout << "为您挑选的最佳路径如下:" << endl;
for (int i = 0; i < visit.size() - 1; i++)
{
cout << c.si[visit[i]].name << "->";
Achieve_shortpath(c, visit[i], visit[i + 1]);
kilo += dist[visit[i]][visit[i + 1]];
}
cout << c.si[visit[visit.size() - 1]].name;
cout << "\t路径总长度为" << kilo << "米" << endl;
}
int main()
{
// 初始化系统
Campus c;
Get_campus(c);
Floyd_shortpath(c);
Display_menu();
Select_choice(c);
}
校园景点导航系统(C with STL)
最新推荐文章于 2024-09-18 18:19:01 发布