数据结构与算法程序设计---景区导游咨询系统

该系统采用C++编程,实现了一个景区导游咨询系统,包括景点信息查询、最短路径计算、所有路径查询等功能。系统利用邻接矩阵和链式前向星数据结构存储图,通过Dijkstra算法和Floyed算法计算最短路径,支持管理员对景点信息的修改和添加,同时具备公告查看和游客留言功能。
摘要由CSDN通过智能技术生成

一.项目要求

 二.技术要求

 三.代码实现

//景区导游咨询系统
#include<iostream>
#include<cstring>
#include<algorithm>;
#include<stack>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 10;
ll dis[maxn];
bool vis[maxn];
int head[maxn],fa[maxn],arr[50];
int E[maxn][maxn],E1[maxn][maxn];            //E邻接矩阵存图,nodes用于Floyed算法中记录途径节点
int path[maxn];
bool vist[maxn];
struct NODE {
	int a;
	int b;
}nodes[maxn][maxn];
void init() {
	for (int i = 0; i <= 1e3; i++) {          //数据重置,方便多次Dijkstra算法查询
		dis[i] = 2147483647;
		vis[i] = 0;
	}
}
void init1() {
	for (int i = 1; i < maxn; i++) {
		fa[i] = i;
	}
}
void init2(){
	for (int i = 0; i < maxn; i++) {
		for (int j = 0; j < maxn; j++) {
			E[i][j] = 0x3f3f3f3f;    //不能到达设为无穷
			E1[i][j] = 0x3f3f3f3f;
			nodes[i][j].a = -1;
		}
	}
}
struct node {           //存储景点编号,名称,信息;
	int num;
	char name[20];
	char introduce[500];
}Map[maxn];
struct edge1 {     
	int u, w, next;
	edge1() {}
	edge1(int _u, int _w, int _next) {     //简化插入操作
		u = _u;
		w = _w;
		next = _next;
	}
}edge[maxn];
struct Edge {                     //用于克鲁斯卡尔算法求最小生成树,即最优路径
	int u, v, w;
}e[maxn];
int flag = 0;   //正数表示增加景点数,负数表示删除景点数;
int cnt=0;
int ans=1;
int top;
int Sum = 0;
void insert1(int u,int v,int w) {     //链式前向星存边
	edge[++cnt] = edge1(v, w, head[u]);// 每一个新节点的next始终指向头结点的next;
	head[u] = cnt;//头结点的next始终指向新结点
}
void insert() {             //初始化平面图(无向图)
	insert1(0, 1, 100);
	e[1].u = 0, e[1].v=1, e[1].w = 100;
	E[0][1] = 100, E[1][0] = 100;
	E1[0][1] = 100, E1[1][0] = 100;
	nodes[0][1].b = 100, nodes[1][0].b = 100;
	insert1(1,2,100);
	e[2].u = 1, e[2].v = 2, e[2].w = 100;
	E[1][2] = 100,E[2][1] = 100;
	E1[1][2] = 100, E1[2][1] = 100;
	nodes[1][2].b = 100, nodes[2][1].b = 100;
	insert1(2, 4, 100);
	e[3].u = 2, e[3].v = 4, e[3].w = 100;
	E[2][4] = 100, E[4][2] = 100;
	E1[2][4] = 100, E1[4][2] = 100;
	nodes[2][4].b = 100, nodes[4][2].b = 100;
	insert1(4, 6, 100);
	e[4].u = 4, e[4].v = 6, e[4].w = 100;
	E[4][6] = 100, E[6][4] = 100;
	E1[4][6] = 100, E1[6][4] = 100;
	nodes[4][6].b = 100, nodes[6][4].b = 100;
	insert1(6, 8, 100);
	e[5].u = 6, e[5].v = 8, e[5].w = 100;
	E[6][8] = 100, E[8][6] = 100;
	E1[6][8] = 100, E1[8][6] = 100;
	nodes[6][8].b = 100, nodes[8][6].b = 100;
	insert1(8, 10, 100);
	e[6].u = 8, e[6].v = 10, e[6].w = 100;
	E[8][10] = 100, E[10][8] = 100;
	E1[8][10] = 100, E1[10][8] = 100;
	nodes[8][10].b = 100, nodes[10][8].b = 100;
	insert1(1, 3, 100);
	e[7].u = 1, e[7].v = 3, e[7].w = 100;
	E[1][3] = 100, E[3][1] = 100;
	E1[1][3] = 100, E1[3][1] = 100;
	nodes[1][3].b = 100, nodes[3][1].b = 100;
	insert1(3, 5, 100);
	e[8].u = 3, e[8].v = 5, e[8].w = 100;
	E[3][5] = 100, E[5][3] = 100;
	E1[3][5] = 100, E1[5][3] = 100;
	nodes[3][5].b = 100, nodes[5][3].b = 100;
	insert1(5, 7, 100);
	e[9].u = 5, e[9].v = 7, e[9].w = 100;
	E[5][7] = 100, E[7][5] = 100;
	E1[5][7] = 100, E1[7][5] = 100;
	nodes[5][7].b = 100, nodes[7][5].b = 100;
	insert1(7, 9, 100);
	e[10].u = 7, e[10].v = 9, e[10].w = 100;
	E[7][9] = 100, E[9][7] = 100;
	E1[7][9] = 100, E1[9][7] = 100;
	nodes[7][9].b = 100, nodes[9][7].b = 100;
	insert1(9, 10, 100);
	e[11].u = 9, e[11].v = 10, e[11].w = 100;
	E[9][10] = 100, E[10][9] = 100;
	E1[9][10] = 100, E1[10][9] = 100;
	nodes[9][10].b = 100, nodes[10][9].b = 100;
	insert1(2, 3, 100);
	e[12].u = 2, e[12].v = 3, e[12].w = 100;
	E[2][3] = 100, E[3][2] = 100;
	E1[2][3] = 100, E1[3][2] = 100;
	nodes[2][3].b = 100, nodes[3][2].b = 100;
	insert1(4, 5, 100);
	e[13].u = 4, e[13].v = 5, e[13].w = 100;
	E[4][5] = 100, E[5][4] = 100;
	E1[4][5] = 100, E1[5][4] = 100;
	nodes[4][5].b = 100, nodes[5][4].b = 100;
	insert1(6, 7, 100);
	e[14].u = 6, e[14].v = 7, e[14].w = 100;
	E[6][7] = 100, E[7][6] = 100;
	E1[6][7] = 100, E1[7][6] = 100;
	nodes[6][7].b = 100, nodes[7][6].b = 100;
	insert1(8, 9, 100);
	e[15].u = 8, e[15].v = 9, e[15].w = 100;
	E[8][9] = 100, E[9][8] = 100;
	E1[8][9] = 100, E1[9][8] = 100;
	nodes[8][9].b = 100, nodes[9][8].b = 100;
}
void creat(){     //图的创建
	Map[0].num = 0;
	for (int i = 1; i < maxn; i++) {
		Map[i].num= i;
	}
	strcpy(Map[0].name, "初始所在地");
	strcpy(Map[1].name, "王村瀑布");
	strcpy(Map[2].name, "迷魂台");
	strcpy(Map[3].name, "张家界国家森林公园");
	strcpy(Map[4].name, "百龙天梯");
	strcpy(Map[5].name, "天子山");
	strcpy(Map[6].name, "十里画廊");
	strcpy(Map[7].name, "天门洞");
	strcpy(Map[8].name, "玉壶峰");
	strcpy(Map[9].name, "盘龙崖玻璃栈道");
	strcpy(Map[10].name, "金鞭溪大峡谷");
	strcpy(Map[1].introduce, "每当天气晴朗,山明水秀之时,水雾弥漫,映出一道七彩虹,这一美景被称为“雪浪飞虹”。");
	strcpy(Map[2].introduce, "迷魂台立台鸟瞰远近宽广的盆地里,高低粗落的翠峰,如楼如阁,如台如榭、如凳如椅、如人如兽、千姿百态、景象万千.");
	strcpy(Map[3].introduce, "中国第一个国家森林公园,世界地质公园, 世界纯自然遗产");
	strcpy(Map[4].introduce, "以“世界上最高、载重量最大、运行速度最快的全暴露户外观光电梯”三项桂冠独步世界。");
	strcpy(Map[5].introduce, "景观、景点都是天造地设,全无人工雕琢痕迹。这里不但有奇山秀水,还有淳朴的民情,奇特的民俗、独具风味的民族食品正等待着各位游客光临");
	strcpy(Map[6].introduce, "峡谷两侧群峰凛然而列,造型各异,组成一幅幅生灵活现的天然雕塑画。");
	strcpy(Map[7].introduce, "“天门吐雾”、“天门霞光”被人誉为举世罕见的景象奇观。");
	strcpy(Map[8].introduce, "相传这只玉壶是仙女麻姑给西王母献酒祝寿之后遗留在这里的,天门山又被称为方壶山正是得名于此峰。");
	strcpy(Map[9].introduce, "远观盘龙崖玻璃栈道,犹如一条巨龙盘卧在山顶。");
	strcpy(Map[10].introduce, "溪水明净,跌宕多姿,小鱼游弋其中。溪畔花草鲜美,鸟鸣莺啼,人沿清溪行,胜似画中游。被誉为“世界上最美丽的峡谷之一”。");
}
void dijkstra(int s,int p) {     //dijkstra算法计算两景点最短路径
	dis[s] = 0;
	int pos = s;
	while (!vis[pos]) {
		ll MIN = 2147483647;
		vis[pos] = true;
		for (int i = head[pos]; ~i; i = edge[i].next) { //~i==i!=-1
			if (!vis[edge[i].u] && dis[edge[i].u] > dis[pos] + edge[i].w) {
				dis[edge[i].u] = dis[pos] + edge[i].w;
			}
		}
		for (int i = 1; i <= 10+flag; i++) {
			if (dis[i] < MIN && vis[i] == 0) {
				MIN = dis[i];
				pos = i;
			}
		}
	}
}
void floyed() {              //Floyed算法连接
	for (int k = 0; k <= 10 + flag; k++) {
		for (int i = 0; i <= 10 + flag; i++) {
			for (int j = 0; j <= 10 + flag; j++) {
				if (E1[i][j] > E1[i][k] + E[k][j]) {
					E1[i][j] = E1[i][k] + E1[k][j];
					nodes[i][j].a = k;
					nodes[i][j].b = E1[i][k] + E1[k][j];
				}
			}
		}
	}
}
void announcement() {   //公告查看及游客留言栏
	cout << '\n';
	cout << "***\t公告查看及游客留言栏\t***" << '\n';
	cout << "***\t公告查看\t***" << '\n';
	cout << "1、请不要将烟头等易燃物品随处乱丢,景区内严禁使用明火。" << '\n';
	cout << "2、请按照景区要求停放车辆。" << '\n';
	cout << "3、登山过程中,量力而行、小心台阶、提防湿滑" << '\n';
	cout << "4、严格遵守国内旅游文明行为公约,注意言行举止,自觉维护公共秩序" << '\n';
	cout << "5、不乱扔垃圾,不涂抹刻画,有序排队、尊老爱幼" << '\n';
	cout << "***\t游客留言栏\t***" << '\n';
	cout << "1.远离城市的喧嚣,远离工作的压力,卸下一切烦恼忧愁,到那一方大自然的净土中去沐浴身心" << '\n';
	cout << "2.旅途开启,祝福传递:温馨送你,与快乐相依" << '\n';
	cout << "3.忘记疲惫抛开烦恼,忙里偷闲享受舒坦" << '\n';
	cout << '\n';
}
void All_attractionsin_quiry() {   //所有景点查询
	cout << '\n';
	cout << "***\t景区平面图\t***" << '\n';
	cout << "编号" << '\t' << "名称" << '\n';
	cout << 0 << '\t' << Map[0].name << '\n';
	for (int i = 1; i <= 10 + flag; i++) {
		cout << Map[i].num << '\t' << Map[i].name << '\n';
	}
	cout << "\t\t\t\t\t" <<"◎" << Map[6].num << "[" << Map[6].name << "]" << '\n';
	cout << '\n';
	cout << "\t\t\t\t" <<"◎"<< Map[4].num << "[" << Map[4].name << "]" << '\n';
	cout << '\n';
	cout << "\t\t\t" <<"◎" << Map[2].num << "[" << Map[2].name << "]" << "\t\t" <<"◎" << Map[8].num << "[" << Map[8].name << "]" << '\n';
	cout << '\n';
	cout <<"◎" << Map[0].num << "[" << Map[0].name << "]" << '\t' <<"◎" << Map[1].num << "[" << Map[1].name << "]" << "\t\t\t\t" <<"◎" << Map[10].num << "[" << Map[10].name << "]" << '\n';
	cout << '\n';
	cout << "\t\t\t" <<"◎" << Map[3].num << "[" << Map[3].name << "]" << "\t" <<"◎" << Map[9].num << "[" << Map[9].name << "]" << '\n';
	cout << '\n';
	cout << "\t\t\t\t" <<"◎" << Map[5].num << "[" << Map[5].name << "]" << '\n';
	cout << '\n';
	cout << "\t\t\t\t\t" <<"◎" << Map[7].num << "[" << Map[7].name << "]" << '\n';
	cout << "新增景点:";
		if (flag == 0)
			cout << "无" << '\n';
	for (int i = 11; i <= 10+flag; i++) {
		cout << Map[i].num << '\t' << Map[i].name << '\n';
	}
	cout << '\n';
}
void floyed_print1(int u, int v) {      //floyed算法
	if (nodes[u][v].a == -1 || nodes[u][v].a == u || nodes[u][v].a == v)
		return;
	else {
		floyed_print1(u, nodes[u][v].a);            //将中间点作为终点继续打印路径
		cout <<Map[nodes[u][v].a].num << Map[nodes[u][v].a].name << "---->";
		floyed_print1(nodes[u][v].a,v);                  //将中间点作为起点继续打印路径
	}
}
int find(int x) {  //找父结点
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}
bool cmp(Edge a, Edge b) {
	return a.w < b.w;
}
void print_the_optimal_path(int n) {   //打印初始地到目的地的最优路径
	int SUM = 100;
	sort(e + 1, e + 1+15+flag, cmp);
	cout << '\n';
	cout <<"***\t"<<Map[0].num << Map[0].name << "到" <<Map[n].name << Map[n].name << "最优路径\t***" << '\n';
	cout <<Map[0].num << Map[0].name << "---->";
	for (int i = 0; i <= 15 + flag; i++) {
		int x = find(e[i].u);
		int y = find(e[i].v);
		if (x == y)continue;
		fa[min(x, y)] = max(x, y);
	}
	floyed();
	floyed_print1(0, n);
	if (n > 10 + flag) {
		for (int j = 0; j <= 10 + flag; j++) {
			if (E1[j][n] != 0x3f3f3f3f) {
				SUM += E1[j][n];
				break;
			}
		}
	}
	cout <<Map[n].num << Map[n].name << '\n';
	cout << "最优路径长度:  " << SUM+(n/2)*100 << '\n';
	SUM = 100;
}
int judg2(int n) {   //景点查询判断界面
	if (n == 0)
		return 0;
	else if (n<0 || n>flag + 10)
		return -1;
	else {
		cout << Map[n].name << '\t' << Map[n].introduce << '\n';
		print_the_optimal_path(n);
		return n;
	}
}
void Attraction_information_inquiry() {   //景点信息查询
	int n;
	cout << '\n';
	cout << "***\t景点信息查询\t***" << '\n';
	while (1) {
		cout << "请输入景点标号:(提醒若想要返回上一界面请输入0)" << '\n';
		cin >> n;
		int k = judg2(n);
		int x = -1;
		if (k == 0) {
			break;
		}
		else if (k == -1) {
			while (x == -1) {
				cout << "输入错误,请重新输入" << '\n';
				cin >> n;
			    x = judg2(n);
				if (x == 0) {
					return;
				}
			}
		}
	}
}
int judg4(int n) {   //修改景点信息判断
	if (n == 0)
		return 0;
	else if (n<0 || n>flag + 10)
		return -1;
	else {
		char s[20], s1[500];
		cout << "输入修改景点名称" << '\n';
		cin >> s;
		strcpy(Map[n].name, s);
		cout << "输入修改景点介绍" << '\n';
		cin >> s1;
		strcpy(Map[n].introduce, s);
	}
}
void modify_Attraction_information(){     //修改景点信息
	int n;
	cout << '\n';
	cout << "***\t景点信息修改\t***" << '\n';
	while (1) {
		cout << "请输入需要修改景点标号:(提醒若想要返回上一界面请输入0)" << '\n';
		cin >> n;
		int k = judg4(n);
		int x = -1;
		if (k == 0) {
			break;
		}
		else if (k == -1) {
			while (x == -1) {
				cout << "输入错误,请重新输入" << '\n';
				cin >> n;
				x = judg4(n);
				if (x == 0) {
					return;
				}
			}
		}
	}
}
int judg6(int u,int v,int w) {     //判断增加景点操作中与新增景点相通的景点的判断
	if (v == 0 && w == 0)
		return 0;
	if (v < 0 || v>10 + flag)
		return -1;
	else {
		insert1(u, v, w);
		e[15 + flag].u = u, e[15 + flag].v = v, e[15 + flag].w = w;
		E[u][v] = w, E[v][u] = w;
		E1[u][v] = w, E1[v][u] = w;
	}
}
int judg5(int n) {    //增加景点操作判断
	if (n == 0)
		return 0;
	else if (n != 10 + flag + 1)
		return -1;
	else {
		   flag++;
			char s[20], s1[500];
			int v, w;
			cout << "请输入新增景点名称:" << '\n';
			cin >> s;
			strcpy(Map[n].name, s);
			cout << "请输入新增景点介绍:" << '\n';
			cin >> s1;
			strcpy(Map[n].introduce, s1);
			while (1) {
				cout << "请输入与新增景点相通的景点以及距离:(提醒若想要返回上一界面请输入0 0)" << '\n';
				cin >> v >> w;
				int k = judg6(n, v, w);
				if (k == 0) {
					break;
				}
				int x = -1;
				if (k == -1) {
					while (x == -1) {
						cout << "输入错误,请重新输入" << '\n';
						cin >> v >> w;
						x = judg6(n, v, w);
						if (x == 0) {
							return 1;
						}
					}
				}
			}
	}
}
void add_attractionsin() {         //增加景点操作
	int n;
	cout << '\n';
	cout << "***\t增加景点\t***" << '\n';
	while (1) {
		cout << "请输入增加景点标号:(提醒若想要返回上一界面请输入0)" << '\n';
		cout << "(温馨提示)增加景点编号需紧接上一编号" << '\n';
		cin >> n;
		int k = judg5(n);
		int x = -1;
		if (k == 0) {
			break;
		}
		else if (k == -1) {
			while (x == -1) {
				cout << "输入错误,请重新输入" << '\n';
				cin >> n;
				x = judg5(n);
				if (x == 0) {
					return;
				}
			}
		}
	}
}
void delete_attractionsin() {       //删除景点操作
	cout << "***\t暂未实现此功能\t***" << '\n';
}
int judg1(int n) {  //管理员判断界面
	if (n == 4)
		return 0;
	else if (n < 1 || n>3)
		return -1;
	else if (n == 1)
		modify_Attraction_information();
	else if (n == 2)
		add_attractionsin();
	else if (n == 3)
		delete_attractionsin();
}
int judg9(int a) {   //管理员登录判断界面
	if (a == 123456)
		return 0;
	else if (a == -1)
		return -2;
	else
		return -1;
}
void Administrators() {   //管理员界面
	cout << '\n';
	cout << "***\t管理员登录\t***" << '\n';
	cout << "密码:(密码为6位)(温馨提示若想要返回上一界面请输入-1)" << '\n';
	int flag1 = 1;
	bool  flag2 = 0;
	while (flag1) {
		int a;
		cin >> a;
		int k = judg9(a);
		if (k == 0) {
			cout << "***\t登录成功\t***"<<'\n';
			break;
		}
		else if (k == -1) {
			while (judg9(a) == -1) {
				cout << "输入错误,请重新输入" << '\n';
				cin >> a;
				if (!judg9(a)) {
					cout << "***\t登录成功\t***" << '\n';
					flag1 = 0;
					break;
				}
				else if (judg9(a) == -2) {
					flag2 = 1;
					flag1 = 0;
					break;
				}
			}
		}
		else {
			flag2 = 1;
			break;
		}
	}
	if (!flag2) {
		cout << "***\t景点管理员后台管理栏\t***" << '\n';
		cout << "请选择功能" << "\n";
		while (1) {
			int n;
			cout << "修改景点信息\t\t\t选择1\n";
			cout << "增加景点\t\t\t选择2\n";
			cout << "删除景点\t\t\t选择3" << '\n';
			cout << "退出景点管理员后台管理栏\t选择4" << '\n';
			cin >> n;
			int k = judg1(n);
			if (k == 0) {
				break;
			}
			if (k == -1) {
				while (judg1(n) == -1) {
					cout << "输入错误,请重新输入" << '\n';
					cin >> n;
					if (!judg1(n))
						return;
				}
			}
		}
	}
}
int judg3(int x, int y) {    //两景点间最短路径查询判断界面
	if (x < 0 || x>10 + flag || y < 0 || y > 10 + flag)
		return -1;
	else if (x == 0 && y == 0)
		return 0;
	else if (x == y) {
		cout << "两景点重合" << '\n';
	}
	else {
		dijkstra(min(x, y), max(x, y));
		if (dis[max(x, y)+1] == 2147483647&&dis[max(x,y)] == 2147483647)
			cout << "无法到达" << '\n';
		else {
			cout << x << Map[x].name << ' ' << y<< Map[y].name << "景点最短路径:";
			if (dis[max(x, y) + 1] != 2147483647)
				cout << dis[max(x, y) + 1] << "米" << '\n';
			else
				cout << dis[max(x, y)] << "米" << '\n';
		}
		init();
	}
}
void The_shortest_distance_between_two_attraction() { //两景点间最短路径查询
	cout << '\n';
	cout << "***\t两景点间最短路径查询***\t" << '\n';
	while (1) {
		cout << "请输入两景点编号:(提醒若想要返回上一界面请输入0 0)" << '\n';
		int x, y;
		cin >> x>>y;
		int z = -1;
		int k = judg3(x,y);
		if (k == 0) {
			break;
		}
		else if (k == -1) {
			while (z == -1) {
				cout << "输入错误,请重新输入" << '\n';
				cin >> x >> y;
				 z = judg3(x,y);
				if (z == 0) {
					return;
				}
			}
		}
	}
}
int dfs(int x,int y) {              //dfs搜所有路径
	path[top] = x;
	top++;
	vist[x] = true;
	for (int i = 0; i <= 10 + flag; i++) {
		if (E[x][i] > 0 && E[x][i] != 0x3f3f3f3f && !vist[i]) {
			Sum = 0;
			if (i == y) {                 //如果搜到终点输出
				cout << "第" << ans++ << "条路:";
				for (int j = 0; j < top; j++) {
					cout << Map[path[j]].name << "---->";
					if (j < top - 1)
						Sum += E[path[j]][path[j + 1]];
				}
				Sum += E[path[top - 1]][y];
				cout << Map[y].name << '\n';
				cout << "总路径长度: " << Sum<<'\n';
			}
			else {
				dfs(i, y);
				top--;            //回溯
				vist[i] = false;
			}
		} 

	}
	return 0;
}
void print_directory(int x, int y) {  //两景点间所有路径查询操作中打印路径
	cout << '\n';
	cout << "***\t" <<Map[x].num << Map[x].name << "到" <<Map[y].num << Map[y].name << "所有路径" << '\n';
	dfs(x,y);
	ans = 1;
	top = 0;
	Sum = 0;
	memset(path, 0, sizeof(path));
	memset(vist, false, sizeof(vist));
}
int judg7(int x, int y) {    //两景点间所有路径查询
	if (x == 0 && y == 0)
		return 0;
	else if (x < 0 || x>10 + flag || y < 0 || y>10 + flag)
		return -1;
	else {
		if (x == y) {
			cout << "初始景点与目的景点相同!" << '\n';
			return  x;
		}
		print_directory(x, y);//打印路径
	}
}
void All_paths_between_the_two_attractions() {  //两景点间所有路径查询
	cout << '\n';
	cout << "***\t两景点所有路径查询\t***" << '\n';
	while (1) {
		cout << "请输入两景点编号:(提醒若想要返回上一界面请输入0 0)" << '\n';
		int x, y;
		cin >> x >> y;
		int z = -1;
		int k = judg7(x, y);
		if (k == 0) {
			break;
		}
		else if (k == -1) {
			while (z == -1) {
				cout << "输入错误,请重新输入" << '\n';
				cin >> x >> y;
				z = judg7(x, y);
				if (z == 0) {
					return;
				}
			}
		}
	}
}
void floyed_print(int u,int v) {      //floyed算法
	if (nodes[u][v].a == -1 || nodes[u][v].a == u || nodes[u][v].a == v)
		return;
	else {
		floyed_print(u, nodes[u][v].a);            //将中间点作为终点继续打印路径
		cout<<Map[nodes[u][v].a].num << Map[nodes[u][v].a].name << "---->";
		floyed_print(nodes[u][v].a, v);                  //将中间点作为起点继续打印路径
	}
}
void print_Multi_attraction_access_route(int cnt) {   //打印多景点间访问路线
	floyed();
	cout << "***\t最佳访问路线\t***"<<'\n';
	for (int i = 0; arr[i] > 0 && arr[i + 1] > 0; i++) {
		cout << Map[arr[i]].name<< "---->";
		floyed_print(arr[i],arr[i+1]);
		Sum += nodes[arr[i]][arr[i + 1]].b;
	}
	cout <<Map[arr[cnt]].name << '\n';
	cout << "最佳访问路线长度:" << Sum << '\n';

}
int judg8(int x) {   //多景点间访问路线查询判断界面
	if (x == 0)
		return 0;
	else if (x < 0 || x>10 + flag)
		return -1;
}
void Multi_attraction_access_route_query() {   //多景点间访问路线查询
	cout << '\n';
	cout << "***\t多景点间访问路线查询\t***" << '\n';
	cout << "请输入多个景点(提醒:请逐个输入并以0为结尾停止输入)" << '\n';
	int x = 1;
	int cnt = 0;
		while (x) {
			int z = -1;
			cin >> x;
			int k = judg8(x);
			if (k == 0) {
				break;
			}
			else if (k == -1) {
				while (z == -1) {
					cout << "输入错误,请重新输入" << '\n';
					cin >> x;
					z = judg8(x);
					if (z == 0) {
						break;
					}
				}
			}
			if (x != 0)
				arr[cnt++] = x;
		}
		sort(arr, arr + cnt);
		print_Multi_attraction_access_route(cnt - 1);//打印多景点间访问路线
		memset(arr, 0, sizeof(arr));
		Sum = 0;
}
int judg(int n)   //判断界面
{
	if (n == 7) {
		cout << "       ┏┓   ┏┓ + +" << '\n';
		cout << "      ┏┛┻━━━┛┻┓ + +" << '\n';
		cout << "      ┃       ┃" << '\n';
		cout << "      ┃   ━   ┃++ + ++" << '\n';
		cout << "       ████━████ ┃ +" << '\n';
		cout << "      ┃       ┃ +" << '\n';
		cout << "      ┃   ┻   ┃" << '\n';
		cout << "      ┃       ┃ + +" << '\n';
		cout << "      ┗━┓   ┏━┛" << '\n';
		cout << "        ┃   ┃" << '\n';
		cout << "        ┃   ┃ + +++" << '\n';
		cout << "        ┃   ┃    " << '\n';
		cout << "        ┃   ┃ +" << '\n';
		cout << "        ┃   ┃" << '\n';
		cout << "         ┃   ┃   +" << '\n';
		cout << "        ┃    ┗━━━┓ + +" << '\n';
		cout << "        ┃        ┣┓" << '\n';
		cout << "        ┃        ┏┛" << '\n';
		cout << "        ┗┓┓┏━┳┓┏┛ + +++" << '\n';
		cout << "           ┃┫┫ ┃┫┫" << '\n';
		cout << "         ┗┻┛ ┗┻┛ + +++" << '\n';
		cout << "***\t感谢您的使用\t***" << '\n';
		return 0;
	}
	else if (n < 1 || n>8)
		return -1;
	else if (n == 6)
		announcement();          公告查看及游客留言栏
	else if (n == 1)
		All_attractionsin_quiry();     //所有景点查询
	else if (n == 8)
		Administrators();            //景点管理员后台管理栏
	else if (n == 2)
		Attraction_information_inquiry();   //景点信息查询
	else if (n == 3)
		The_shortest_distance_between_two_attraction();//两景点间最短路径查询
	else if (n == 4)
		All_paths_between_the_two_attractions();//两景点间所有路径查询
	else if (n == 5)
		Multi_attraction_access_route_query();//多景点间访问路线查询
}
int Guest_interface() {                //游客登录界面
	while (1) {
		int n;
		cout << "景区平面图查询\t\t选择1\n";
		cout << "景区景点信息查询\t选择2\n";
		cout << "两景点间最短路径查询\t选择3" << '\n';
		cout << "两景点间所有路径查询\t选择4" << '\n';
		cout << "多景点间访问路线查询\t选择5" << '\n';
		cout << "公告查看及游客留言栏\t选择6" << '\n';
		cout << "退出景区导游咨询系统\t选择7" << '\n';
		cin >> n;
		int k = judg(n);
		if (k == 0) {
			break;
		}
		if (k == -1) {
			while (judg(n) == -1) {
				cout << "输入错误,请重新输入" << '\n';
				cin >> n;
				if (!judg(n))
					return 0;
			}
		}
	}
}
int judg10(int x) {
	if (x == 1 || x == 2)
		return x;
	else {
		return -1;
	}
}
int main()    
{
	ios::sync_with_stdio(false);
	memset(head, -1, sizeof(head));
	init();
	init1();
	init2();
	creat();
	insert();
	cout << "***\t欢迎进入景区导游咨询系统\t***" << '\n';
	cout << "                ********" << '\n';
	cout << "               ************" <<'\n';
	cout << "               ####....#." << '\n';
	cout << "             #..###.....##...." << '\n';
	cout << "             ###.......######              ###                 ###           ###           ###" << '\n';
	cout << "                ...........               #...#               #...#         #...#         #...#" << '\n';
	cout << "               ##*#######                 #.#.#               #.#.#         #.#.#         #.#.#" << '\n';
	cout << "            ####*******######             #.#.#               #.#.#         #.#.#         #.#.#" << '\n';
	cout << "           ...#***.****.*###....          #...#               #...#         #...#         #...#" <<'\n';
	cout << "           ....**********##.....           ###                 ###           ###           ###" << '\n';
	cout << "           ....****    *****...." << '\n';
	cout << "             ####        ####" << '\n';
	cout << "           ######        ######" <<'\n';
	while (1) {
		cout << "请选择登录方式" << "\n";
		int x;
		cout << "\t\t\t--------------\t\t\t  ----------" << '\n';
		cout << "\t\t\t|1.管理员登录|\t\t\t2.|游客登录|" << '\n';
		cout << "\t\t\t--------------\t\t\t  ----------" << '\n';
		cin >> x;
		int z = judg10(x);
		if (z == 2) {
			Guest_interface();
		}
		else if(x==1) {
			judg(8);
		}
		else {
			while (judg10(x) == -1) {
				cout << "输入错误,请重新输入" << '\n';
				cin >> x;
				if(x==2)
					Guest_interface();
				else if(x==1)
					judg(8);
			}
		}
	}
	return 0;
}

四.总结

1.数据结构上:选用邻接矩阵,链式前向星,存图,然后建立结构体数组储存景点编号,名称,介绍

2.选项功能:可通过多个if语句实现,额外判断输入错误情况,还要实现连续输入错误情况下依旧可跳至功能

3.计算两点之间最短路径:选用链式前向星存图结构,Dijkstra算法,

用数组dis记录起点到每个结点的最短路径,
//bool 数组vis表示是否来过,dis[s]=0,其余为2的31次方-1,
//定义pos变量代表现在的位置,vis[pos]=true表示来过,初始值为起点
//枚举所有与pos相连的点:更新dis[i]按照:dis[i]=min(dis[i],dis[pos]+w)
//枚举所有未被标记的点,找到dis最小的点赋值给pos,vis[pos]==true;
//所有点都访问过程序结束。此时,dis[i]代表从起点到i的最短路径

4.计算两点之间的所有路径:选用邻接矩阵的存图方式,dfs深搜。即建立一个栈,将与之起点相连的入栈,深搜下去,遇到结果,输出,不断回溯深搜到所有路径

5.查询景点信息并推荐最优路径:推荐最优路径本来选用的是克鲁斯卡尔算法,但初始地图设计使部分景点最优路径会绕圈,于是选用邻接矩阵Floyed算法计算最短路径,只需在Floyed算法中设立二维数组nodes,记录两个景点之间的结点,在输出路径时,只要两个景点之间有结点,就递归将中间点作为终点继续打印路径和将中间点作为起点继续打印路径,遇见nodes[u][v]=-1或等于起点或等于终点就返回;

void floyed_print1(int u, int v) {      //floyed算法
	if (nodes[u][v].a == -1 || nodes[u][v].a == u || nodes[u][v].a == v)
		return;
	else {
		floyed_print1(u, nodes[u][v].a);            //将中间点作为终点继续打印路径
		cout <<Map[nodes[u][v].a].num << Map[nodes[u][v].a].name << "---->";
		floyed_print1(nodes[u][v].a,v);                  //将中间点作为起点继续打印路径
	}
}

6.查询多个景点最优路径:只需将景点编号储存,并按照从大到小排序,之后操作如5

7.管理员修改景点功能只需找到景点编号,将景点名称,介绍修改即可,增加景点功能只需将填写景点名称,介绍,将与各节点距离插入链式前向星和邻接矩阵中即可,删除景点操作,因为之前功能实现,没考虑到删除景点操作,一但增加此操作,便会改动全局,没有实现。

8.公告栏,退出界面,进入界面设计好封面即可,麻烦操作就是判断功能选项和输入数据是否合理

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值