制作一个简单的大学城导航系统,根据用户指定的起点和终点,求出最短路径长度以及具体路径。
项目要求:
1)程序与数据相分离,地图中的所有数据都是从文件读入,而不是写在代码中
2)最短路径算法不能调用函数库
3)菜单界面可以循环显示,每次显示前先清屏
4)输入的起点和终点若不存在,能给出相应提示并允许重新输入(有可能多次输入都不存在) 5)能够显示两个地点的简介
6)能够根据起点和终点计算出正确的最短路径长度
7)能够显示出具体的最短路径(比如:中大 -> 广外->广中医)
8)如果起点与终点之间不可达,要有相应提示。 本地图中,只有鲤鱼岗不可达,如果代码中根据起点或终点直接判断是否鲤鱼岗来得出不可达的结论,则代码不达标,必须是由最短路径算法运算后来判断是否可达。
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
const int MAX = 100;
int map[MAX][MAX]; // 地点间的邻接矩阵
string name[MAX]; //地点名称表
string intro[MAX]; // 地点简介
int n, m; // 地点个数和边的个数
//打开数据文件 函数
bool read(const char* filename) {
ifstream file(filename);
if (!file) {
return false;
}
file >> n >> m; //读入地点个数和边的个数
for (int i = 1; i <= n; ++i) { //初始化邻接矩阵
for (int j = 1; j <= n; ++j) {
map[i][j] = -1;
}
}
int u, v, w;
for (int i = 0; i < m; ++i) { //建立邻接矩阵
file >> u >> v >> w;
map[u][v] = w;
map[v][u] = w;
}
file.ignore();
for (int i = 1; i <= n; ++i) {
getline(file, name[i]); //建立地点名称表
}
for (int i = 1; i <= n; ++i) {
getline(file, intro[i]); //读入地点简介
}
file.close();
return true;
}
// 打印地点列表 函数
void display() {
for (int i = 1; i <= n; ++i) {
cout <<" "<< i << "-" << name[i] ;
if(i%4==0) cout<<endl<<endl;
}
}
//Dijkstra算法求最短路径 函数
void dj(int start, int end, int& minDist, int path[]) {
//path存储起点到各个节点的最短距离
bool visited[MAX]; //visited记录结点是否被访问过
int dist[MAX]; //dist存储起点到各个节点的最短距离
for (int i = 1; i <= n; ++i) {
visited[i] = false; //1初始化
dist[i] = INT_MAX;
}
dist[start] = 0;
for (int i = 1; i <= n; ++i) {
int u = -1;
int minDist = INT_MAX;
for (int j = 1; j <= n; ++j) { //2在dist中选出未被访问的最小值,赋值给 u
if (!visited[j] && dist[j] < minDist) {
u = j;
minDist = dist[j];
}
}
if (u == -1) {
break;
}
visited[u] = true;
for (int v = 1; v <= n; ++v) { //3比较 ,更新dist
if (!visited[v] && map[u][v] != -1 && dist[u] + map[u][v] < dist[v]) {
dist[v] = dist[u] + map[u][v];
path[v] = u;
}
}
}
minDist = dist[end];
}
// 输出具体路径的函数
void Minpath(int start, int end, int path[]) {
if (start == end) {
cout << name[start];
return;
}
Minpath(start, path[end], path);
cout << " -> " << name[end];
}
int main() {
const char* filename = "map.txt";
if (!read(filename)) {
cout << "无法读取地图数据文件。" << endl;
return 1;
}
int start, end;
while (true) {
system("cls"); //清屏
cout << "-------------------------广州大学城简易导航系统-----------------------" << endl;
cout<<endl;
display();
cout<<" 0-退出"<<endl;
cout << "----------------------------------------------------------------------"<<endl;
cout << "请输入起点编号:";
cin >> start;
if (start == 0) {
cout << "欢迎再次使用!" << endl;
break;
}
while(start < 1 || start > n) {
cout << "编号不存在,请重新输入"<<endl;
cout << "请输入起点编号:";
cin >> start;
}
cout << "请输入终点编号:";
cin >> end;
if (end == 0) {
cout << "欢迎再次使用!" << endl;
break;
}
while(end < 1 || end > n) {
cout << "编号不存在,请重新输入"<<endl;
cout << "请输入终点编号:";
cin >> end;
}
cout << endl;
cout << intro[start] << endl; //输出简介
cout << endl;
cout << intro[end] << endl;
cout << endl;
int minDist, path[MAX];
dj(start, end, minDist, path); //计算最短路径
if (minDist == INT_MAX) {
cout << name[start] << " 到 " << name[end] << "的最短路径是:无法到达。" << endl;
} else {
cout << name[start] << " 到 " << name[end] << "的最短距离是:" << minDist <<"m"<<endl;
cout<<endl;
cout << "具体路径是:";
Minpath(start, end, path); //输出路径
cout << endl;
}
cout << "按任意键继续...";
cin.ignore();
cin.get();
}
return 0;
}