实现效果
欢迎界面
创建景点景区图
查询景点信息
旅游景点导航
搜索最短路径
铺设电路规划
实验资源
Edge.txt
0 2 700
0 4 1000
0 5 600
1 2 1000
1 6 1000
2 3 400
3 4 300
3 6 400
4 5 600
5 6 500
Vex.txt
7
0
A区
风景优美,气候宜人。门票10元。
1
B区
风景优美,气候宜人。门票20元。
2
C区
风景优美,气候宜人。门票30元。
3
D区
风景优美,气候宜人。门票40元。
4
E区
风景优美,气候宜人。门票50元。
5
F区
风景优美,气候宜人。门票60元。
6
G区
风景优美,气候宜人。门票70元。
源码
Graph.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"Graph.h"
extern Graph m_Graph;
void Init(void)
{
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
m_Graph.m_aAdjMatrix[i][j] = 0;
}
m_Graph.m_nVexNum = 0;
}
}
bool InsertVex(Vex sVex)
{
if (m_Graph.m_nVexNum == 20) {
return false;
}
m_Graph.m_aVexs[m_Graph.m_nVexNum++] = sVex;
return true;
}
bool InsertEdge(Edge sEdge)
{
if (sEdge.vex1 < 0 || sEdge.vex1 >= m_Graph.m_nVexNum || sEdge.vex2 < 0 || sEdge.vex2 >= m_Graph.m_nVexNum) {
return false;
}
m_Graph.m_aAdjMatrix[sEdge.vex1][sEdge.vex2] = sEdge.weight;
m_Graph.m_aAdjMatrix[sEdge.vex2][sEdge.vex1] = sEdge.weight;
return true;
}
Vex GetVex(int v)
{
return m_Graph.m_aVexs[v];
}
int FindEdge(int nVex, Edge aEdge[])
{
int k = 0;
for (int i = 0; i < 20; i++) {
if (m_Graph.m_aAdjMatrix[nVex][i] != 0 && nVex != i) {
aEdge[k].vex1 = nVex;
aEdge[k].vex2 = i;
aEdge[k].weight = m_Graph.m_aAdjMatrix[nVex][i];
k++;
}
}
return k;
}
void DFS(int nVex, bool isVisited[], int& nIndex, PathList& pList)
{
isVisited[nVex] = true;
pList->vexs[nIndex++] = nVex;
int num = 0;
for (int i = 0; i < m_Graph.m_nVexNum; i++) {
if (isVisited[i]) {
num++;
}
}
if (num == m_Graph.m_nVexNum) {
pList->next = new Path;
for (int i = 0; i < m_Graph.m_nVexNum; i++) {
pList->next->vexs[i] = pList->vexs[i];
}
pList = pList->next;
pList->next = NULL;
}
else {
for (int w = 0; w < m_Graph.m_nVexNum; w++) {
if (m_Graph.m_aAdjMatrix[nVex][w] > 0 && !isVisited[w]) {
DFS(w, isVisited, nIndex, pList);
isVisited[w] = false;
nIndex--;
}
}
}
}
void DFSTraverse(int nVex, PathList& pList)
{
int nIndex = 0;
bool bVisited[20] = {
false };
DFS(nVex, bVisited, nIndex, pList);
}
int FindShortPath(int nVexStart, int nVexEnd, Edge aPath[])
{
int nShortPath[20][20];
int nShortDistance[20];
bool aVisited[20];
int v;
for (v = 0; v < m_Graph.m_nVexNum; v++) {
aVisited[v] = false;
if (m_Graph.m_aAdjMatrix[nVexStart][v] != 0) {
nShortDistance[v] = m_Graph.m_aAdjMatrix[nVexStart][v];
}
else {
nShortDistance[v] = 0x7FFFFFFF;
}
nShortPath[v][0] = nVexStart;
for (int w = 1; w < m_Graph.m_nVexNum; w++) {
nShortPath[v][w] = -1;
}
}
aVisited[nVexStart] = true;
int min;
for (int i = 1; i < m_Graph.m_nVexNum; i++) {
min = 0x7FFFFFFF;
bool bAdd = false;
for (int w = 0; w < m_Graph.m_nVexNum; w++) {
if (!aVisited[w] && nShortDistance[w] < min) {
v = w;
min = nShortDistance[w];
bAdd = true;
}
}
if (!bAdd) {
break;
}
aVisited[v] = true;
nShortPath[v][i] = v;
for (int w = 0; w < m_Graph.m_nVexNum; w++) {
if (!aVisited[w] && (min + m_Graph.m_aAdjMatrix[v][w] < nShortDistance[w]) && (m_Graph.m_aAdjMatrix[v][w] > 0)) {
nShortDistance[w] = min + m_Graph.m_aAdjMatrix[v][w];
for (int i = 0; i < m_Graph.m_nVexNum; i++) {
nShortPath[w][i] = nShortPath[v][i];
}
}
}
}
int nIndex = 0;
int nVex1 = nVexStart;
for (int i = 1; i < m_Graph.m_nVexNum; i++) {
if (nShortPath[nVexEnd][i] != -1) {
aPath[nIndex].vex1 = nVex1;
aPath[nIndex].vex2 = nShortPath[nVexEnd][i];
aPath[nIndex].weight = m_Graph.m_aAdjMatrix[nVex1][aPath[nIndex].vex2];
nVex1 = nShortPath[nVexEnd][i];
nIndex++;
}
}
return nIndex;
}
void FindMinTree(Edge aPath[])
{
bool aVisited[20] = {
false };
aVisited[0] = true;
int min;
int nVex1, nVex2;
for (int k = 0; k < m_Graph.m_nVexNum - 1; k++) {
min = 0X7FFFFFFF;
for (int i = 0; i < m_Graph.m_nVexNum; i++) {
if (aVisited[i]) {
for (int j = 0; j < m_Graph.m_nVexNum; j++) {
if (!aVisited[j]) {
if ((m_Graph.m_aAdjMatrix[i][j] < min) && (m_Graph.m_aAdjMatrix[i][j] != 0)) {
nVex1 = i;
nVex2 = j;
min = m_Graph.m_aAdjMatrix[i][j];
}
}
}
}
}
aPath[k].vex1 = nVex1;
aPath[k].vex2 = nVex2;
aPath[k].weight = m_Graph.m_aAdjMatrix[nVex1][nVex2];
aVisited[nVex1] = true;
aVisited[nVex2] = true;
}
}
Graph.h
#pragma once
struct Vex
{
int num;
char name[20];
char desc[1024];
};
struct Edge
{
int vex1;
int vex2;
int weight;
};
struct Graph
{
int m_aAdjMatrix[20][20];
Vex m_aVexs[20];
int m_nVexNum;
};
typedef struct Path
{
int vexs[20];
Path* next;
}*PathList;
void Init(void);
bool InsertVex(Vex sVex);
bool InsertEdge(Edge sEdge);
Vex GetVex(int v);
int FindEdge(int v, Edge aEdge[]);
void DFS(int nVex, bool isVisited[], int& nIndex, PathList& pList);
void DFSTraverse(int nVex, PathList& pList);
int FindShortPath(int nVexStart, int nVexEnd, Edge aPath[]);
void FindMinTree(Edge aPath[]);
main.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"Tourism.h"
#include"Graph.h"
using namespace std;
Graph m_Graph;
int main(void)
{
int choice;
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\t\t\t\t");
printf("*欢迎进入景区管理系统*");
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\t\t\t\t");
system("pause");
system("cls");
do {
cout << "=====景区信息管理系统=====" << endl;
cout << "* 1.创建景区景点图 *" << endl;
cout << "* 2.查询景点信息 *" << endl;
cout << "* 3.旅游景点导航 *" << endl;
cout << "* 4.搜索最短路径 *" << endl;
cout << "* 5.铺设电路规划 *" << endl;
cout << "* 0.退出 *" << endl;
cout << "==========================" << endl;
cout << "请输入菜单项编号(0-5):";
cin >> choice;
cout << endl;
switch (choice)
{
case 1:CreateGraph(); break;
case 2:GetSpotInfo(); break;
case 3:TravelPath(); break;
case 4:FindShortPath(); break;
case 5:DesignPath(); break;
case 0:cout << "谢谢您使用本系统!" << endl; break;
default:cout << "您的输入有误!请重新输入!" << endl << endl;;
}
} while (choice != 0);
return 0;
}
Tourism.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
#include <string.h>
#include<stdlib.h>
#include"Graph.h"
using namespace std;
extern Graph m_Graph;
void LoadVex(void)
{
ifstream VexFile("Vex.txt");
if (!VexFile) {
cout << "Vex.txt文件打开失败,请检查!" << endl;
return;
}
char num[2];
char name[20];
char desc[1024];
Vex sVex;
VexFile.getline(num, 2);
cout << "景区数目:" << atoi(num) << endl;
cout << "-----顶点-----" << endl;
while (VexFile.getline(num, 2)) {
sVex.num = atoi(num);
VexFile.getline(name, 20);
strcpy(sVex.name, name);
VexFile.getline(desc, 1024);
strcpy(sVex.desc, desc);
cout << sVex.num << "-" << sVex.name << endl;
if (!InsertVex(sVex)) {
cout << "新增景点失败!" << endl;
continue;
}
}
cout << "------------" << endl;
VexFile.close();
}
void LoadPath()
{
ifstream EdgeFile("Edge.txt");
if (!EdgeFile) {
cout << "Edge.txt文件打开失败,请检查!" << endl;
return;
}
Edge edge;
cout << "------边------" << endl;
while (EdgeFile) {
EdgeFile >> edge.vex1 >> edge.vex2 >> edge.weight;
cout << "<" << edge.vex1 << "," << edge.vex2 << "> " << edge.weight << endl;
if (!InsertEdge(edge)) {
cout << "新增路径信息失败!" << endl;
continue;
}
}
cout << "-------------" << endl;
EdgeFile.close();
cout << "======================" << endl;
}
void CreateGraph(void)
{
cout << "\n=====创建景点景区图=====" << endl;
Init();
LoadVex();
LoadPath();
cout << endl;
}
void GetSpotInfo(void)
{
cout << "\n=====查询景点信息=====" << endl;
int nVexNum = m_Graph.m_nVexNum;
if (nVexNum == 0) {
cout << "请先创建图!" << endl;
return;
}
for (int i = 0; i < m_Graph.m_nVexNum; i++) {
Vex sVex = GetVex(i);
cout << i << "-" << sVex.name << endl;
}
cout << "====================" << endl;
cout << "\n请输入想要查询的景点编号:";
int num;
cin >> num;
if (num < 0 || num >= m_Graph.m_nVexNum) {
cout << "您的输入有误!请重新输入!" << endl;
cout << "\n请输入想要查询的景点编号:";
cin >> num;
}
else {
Vex sVex = GetVex(num);
cout << "----------------------------" << endl;
cout << sVex.name << ":" << sVex.desc << endl;
cout << "----------------------------" << endl;
cout << "-----周边景区-----" << endl;
Edge aEdge[20];
int EdgeNum = FindEdge(num, aEdge);
for (int i = 0; i < EdgeNum; i++) {
Vex v1 = GetVex(aEdge[i].vex1);
Vex v2 = GetVex(aEdge[i].vex2);
cout << v1.name << "->" << v2.name << " " << aEdge[i].weight << "m" << endl;
}
cout << "------------------" << endl;
}
cout << endl;
}
void TravelPath()
{
cout << "\n=======旅游景点导航======" << endl;
int nVexNum = m_Graph.m_nVexNum;
if (nVexNum == 0) {
cout << "请先创建图!" << endl;
return;
}
for (int i = 0; i < m_Graph.m_nVexNum; i++) {
Vex sVex = GetVex(i);
cout << "*\t" << i << "-" << sVex.name << "\t\t*" << endl;
}
cout << "=========================" << endl;
cout << "请输入想要导航的起始点编号:";
int startNum;
cin >> startNum;
if (startNum < 0 || startNum >= m_Graph.m_nVexNum) {
cout << "您输入的编号有误!" << endl;
return;
}
PathList pList = new Path;
PathList pHead = pList;
DFSTraverse(startNum, pList);
cout << endl;
cout << "导航路线为:" << endl;
int i = 1;
pList = pHead;
while (pList->next != NULL) {
Vex vex = GetVex(pList->vexs[0]);
cout << "路线" << i++ << ":" << vex.name;
for (int j = 1; j < m_Graph.m_nVexNum; j++) {
vex = GetVex(pList->vexs[j]);
cout << "->" << vex.name;
}
cout << endl;
pList = pList->next;
}
cout << endl;
delete pList;
pList = NULL;
pHead = NULL;
}
void FindShortPath(void)
{
cout << "\n======搜索最短路径======\n";
int nVexNum = m_Graph.m_nVexNum;
if (nVexNum == 0) {
cout << "请先创建图!" << endl;
return;
}
for (int i = 0; i < m_Graph.m_nVexNum; i++) {
Vex sVex = GetVex(i);
cout << "*\t" << i << "-" << sVex.name << "\t\t*" << endl;
}
cout << "========================\n";
int start_place, end_place;
cout << "请输入起点的编号:";
cin >> start_place;
cout << "请输入终点的编号:";
cin >> end_place;
if (start_place < 0 || start_place >= m_Graph.m_nVexNum || end_place < 0 || end_place >= m_Graph.m_nVexNum) {
cout << "输入错误!请重新输入!!!" << endl;
return;
}
Edge aPath[20];
for (int i = 0; i < 20; i++) {
aPath->vex1 = -1;
aPath->vex2 = -1;
aPath->weight = -1;
}
int index = FindShortPath(start_place, end_place, aPath);
int length = 0;
Vex sVex = GetVex(aPath[0].vex1);
cout << "\n最短路径为:" << sVex.name;
for (int i = 0; i < index; i++) {
sVex = GetVex(aPath[i].vex2);
cout << "->" << sVex.name;
length += aPath[i].weight;
}
cout << endl;
cout << "最短距离为:" << length << "米" << endl << endl;
}
void DesignPath()
{
cout << "在以下两个景点之间铺设电路";
cout << "\n=======铺设电路规划=======" << endl;
Edge aPath[20];
FindMinTree(aPath);
int nVexNum = m_Graph.m_nVexNum;
if (nVexNum == 0) {
cout << "请先创建图!" << endl;
return;
}
int nAllLength = 0;
for (int i = 0; i < m_Graph.m_nVexNum - 1; i++) {
Vex nVex1 = GetVex(aPath[i].vex1);
Vex nVex2 = GetVex(aPath[i].vex2);
cout << "\t" << nVex1.name << "-" << nVex2.name << ":" << aPath[i].weight << "m" << endl;
nAllLength += aPath[i].weight;
}
cout << "==========================\n";
cout << "铺设电路的总长度是:" << nAllLength << "m" << endl << endl;
}
Tourism.h
#pragma once
void CreateGraph(void);
void GetSpotInfo(void);
void TravelPath();
void FindShortPath(void);
void DesignPath();