#include <string.h> #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <conio.h> #define MAX 100000 #define NUM 30 #define FALSE 0 #define TURE 1 typedef struct ArcNode { int length; /* 路径长度 */ } ArcNode, *ArcLink; /* 边结点的定义 */ typedef struct VertexNode { int number; /* 景点的编号 */ char *name; /* 景点的名称 */ char *info; /* 景点的简介 */ } VertexNode; /* 顶点结点的定义 */ typedef struct Graph { VertexNode vertex[NUM]; ArcNode arc[NUM][NUM]; int vexnum, arcnum; /* 图的顶点数,边数 */ } Graph; /* 图的定义 */ void Map(); /* 校园地图 */ void CreateGraph(); /* 创建图 */ void OutputPlace(); /* 输出景点列表 */ void SearchPlace(); /* 查询景点信息 */ void SearchPath(); /* 查询最短路径 */ void Shortpath( int i ); /* 计算最短路径 */ void output( int sight1, int sight2 ); /* 输出函数 */ Graph G; int path[NUM][NUM]; int D[NUM]; void CreateGraph() /* 创建图 */ { int i, j; G.vexnum = 14; G.arcnum = 28; for ( i = 1; i < NUM; i++ ) G.vertex[i].number = i; G.vertex[1].name = "学校正门"; G.vertex[1].info = "学校正门位于学校的正北方向、是进入学校前的第一道亮丽的风景线!\n"; G.vertex[2].name = "行政楼"; G.vertex[2].info = "行政楼是学校行政人员工作、以及学校重大会议召开的地点!\n"; G.vertex[3].name = "教学楼"; G.vertex[3].info = "教学楼是学生学习上课的地方,分A、B两栋。\n\t\t\t\t\t\t其中A栋楼有7层,1-5层为各种教学使用;6-7层以英语听力课程教室为主!\n\t\t\t\t\t\tB栋共有三层楼、教室较为宽敞、至少可容纳二百多人共同学习!\n"; G.vertex[4].name = "喷泉"; G.vertex[4].info = "喷泉是进入学校后的第一道风景线,位于学校的正门口;\n\t\t\t\t\t\t造型似一只鸽子,乃学校的标志性建筑之一!\n"; G.vertex[5].name = "实验楼"; G.vertex[5].info = "学校实验楼乃是学校各项重大成果诞生的地方、共有三栋!\n\t\t\t\t\t\t可供不同专业、不同兴趣的学生丰富自己的知识、拓展自己的视野!\n"; G.vertex[6].name = "大学生活动中心"; G.vertex[6].info = "大学生活动中心是我校专为学生设计、展现自己各种特长才艺的地方!\n\t\t\t\t\t\t每周这里都会有非常精彩的活动、晚会;乃才艺高人的聚集地!\n"; G.vertex[7].name = "图书馆"; G.vertex[7].info = "图书馆内设多种书库,有几百万的丰富藏书!平时这里学习氛围浓重、\n\t\t\t\t\t\t是知识的天堂!\n"; G.vertex[8].name = "洗浴中心"; G.vertex[8].info = "洗浴中心是学生洗浴的地方!\n"; G.vertex[9].name = "体育馆"; G.vertex[9].info = "体育馆是一个室内的小型体育场;内设有篮球场,羽毛球场及乒乓球场等\n"; G.vertex[10].name = "体育场"; G.vertex[10].info = "体育场是举行大型赛事的地点,平时主要各种足球训练、比赛使用;\n\t\t\t\t\t\t也是同学们跑步健身的好场所!"; G.vertex[11].name = "土操场"; G.vertex[11].info = "土操场主要供学生平时运动、跑步使用;其侧面还有乒乓球、网球场地;\n\t\t\t\t\t\t是同学们课外活动的地点之一!\n"; G.vertex[12].name = "篮球场"; G.vertex[12].info = "篮球场是同学们篮球课程及锻炼球技的地方,也是篮球比赛的重要场所!\n"; G.vertex[13].name = "美食广场"; G.vertex[13].info = "美食广场是学校的两大食堂之一、饭菜美味可口!\n"; G.vertex[14].name = "旭日苑"; G.vertex[14].info = "旭日苑是学校的另一食堂;共分三层,饭菜种类繁多,可品尝到各种美味!\n"; for ( i = 0; i < NUM; ++i ) for ( j = 0; j < NUM; ++j ) G.arc[i][j].length = MAX; G.arc[1][2].length = G.arc[2][1].length = 70; G.arc[1][3].length = G.arc[3][1].length = 100; G.arc[2][4].length = G.arc[4][2].length = 60; G.arc[1][4].length = G.arc[4][1].length = 40; G.arc[4][3].length = G.arc[3][4].length = 80; G.arc[2][6].length = G.arc[6][2].length = 100; G.arc[4][6].length = G.arc[6][4].length = 100; G.arc[5][3].length = G.arc[3][5].length = 100; G.arc[5][6].length = G.arc[6][5].length = 100; G.arc[4][7].length = G.arc[7][4].length = 140; G.arc[6][7].length = G.arc[7][6].length = 80; G.arc[7][5].length = G.arc[5][7].length = 80; G.arc[8][7].length = G.arc[7][8].length = 100; G.arc[9][7].length = G.arc[7][9].length = 80; G.arc[5][8].length = G.arc[8][5].length = 100; G.arc[5][12].length = G.arc[12][5].length = 120; G.arc[9][14].length = G.arc[14][9].length = 60; G.arc[6][10].length = G.arc[10][6].length = 150; G.arc[7][10].length = G.arc[10][7].length = 100; G.arc[12][8].length = G.arc[8][12].length = 50; G.arc[10][9].length = G.arc[9][10].length = 30; G.arc[9][12].length = G.arc[12][9].length = 70; G.arc[13][8].length = G.arc[8][13].length = 30; G.arc[13][12].length = G.arc[12][13].length = 40; G.arc[11][12].length = G.arc[12][11].length = 20; G.arc[11][14].length = G.arc[14][11].length = 30; G.arc[13][14].length = G.arc[14][13].length = 120; G.arc[10][14].length = G.arc[14][10].length = 120; } void Map() /* 学校地图 */ { printf( "\n\n" ); system( "cls" ); printf( "\t\t\t\t\t\t┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n" ); printf( "\t\t\t\t\t\t┃ 西安邮电学院校园图 ┃\n" ); printf( "\t\t\t\t\t\t┃ 注:此图按正门布局而画,方位并非上北下南左西右东! ┃\n" ); printf( "\t\t\t\t\t\t┣━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n" ); printf( "\t\t\t\t\t\t┃ ┏━━━┓ ┃\n" ); printf( "\t\t\t\t\t\t┃ ╔═══╦══┫旭日苑┣═══════╗ ┃\n" ); printf( "\t\t\t\t\t\t┃ ║ ║ ┗┳━┳┛ ║ ┃\n" ); printf( "\t\t\t\t\t\t┃ ║ ║ ║ ║ ║ ┃\n" ); printf( "\t\t\t\t\t\t┃ ┏┻┓ ┏┻┓ ║┏┻━━━━┓ ┏━┻━┓ ┃\n" ); printf( "\t\t\t\t\t\t┃ ┃体┃ ┃体┃ ║┃ 土操场 ┃ ┃ 美食 ┃ ┃\n" ); printf( "\t\t\t\t\t\t┃ ┃育┣═┫育┃ ║┃ ┃ ┃ 广场 ┃ ┃\n" ); printf( "\t\t\t\t\t\t┃ ┃场┃ ┃馆┣══╬╋━━━━━┫ ┃ ┃ ┃\n" ); printf( "\t\t\t\t\t\t┃ ┗┳┛ ┗┳┛ ║┃ 篮球场 ┣═┻━┳━┛ ┃\n" ); printf( "\t\t\t\t\t\t┃ ║ ║ ║┃ ┃ ║ ┃\n" ); printf( "\t\t\t\t\t\t┃ ║ ║ ║┗━━━━━┛ ║ ┃\n" ); printf( "\t\t\t\t\t\t┃ ║┏━━╩━━┓║ ┏━┻━━┓ ┃\n" ); printf( "\t\t\t\t\t\t┃ ╔╩┫ 图书馆 ┣╬══════╦═┫洗浴中心┃ ┃\n" ); printf( "\t\t\t\t\t\t┃ ║ ┗━━┳━━┛║ ║ ┗━━━━┛ ┃\n" ); printf( "\t\t\t\t\t\t┃┏┻━┓ ║ ║ ┏━┻━━━┓ ┃\n" ); printf( "\t\t\t\t\t\t┃┃大学┃ ║ ║ ┃ 实 ┃ ┃\n" ); printf( "\t\t\t\t\t\t┃┃生活┃ ║ ║ ┃ 验 ┃ ┃\n" ); printf( "\t\t\t\t\t\t┃┃动中┣══╬═══╬════┫ 楼 ┃ ┃\n" ); printf( "\t\t\t\t\t\t┃┃ 心 ┃ ║ ║ ┗━━┳━━┛ ┃\n" ); printf( "\t\t\t\t\t\t┃┗━┳┛ ║ ║ ║ ┃\n" ); printf( "\t\t\t\t\t\t┃ ║ ┏┻━┓ ║ ┏━━┻━━┓ ┃\n" ); printf( "\t\t\t\t\t\t┃ ║ ┃喷泉┣═╬════┫ 教学楼 ┃ ┃\n" ); printf( "\t\t\t\t\t\t┃ ║ ┗┳━┛ ║ ┗━━┳━━┛ ┃\n" ); printf( "\t\t\t\t\t\t┃┏━┻━┓ ║ ║ ║ ┏━━━┓ ┃\n" ); printf( "\t\t\t\t\t\t┃┃行政楼┣═╩═══╬═══════╝ ┃ 南 ┃ ┃\n" ); printf( "\t\t\t\t\t\t┃┗━━━┛ ┏━━┻━━┓ ┃东╋西┃ ┃\n" ); printf( "\t\t\t\t\t\t┃ ┃ 学校正门 ┃ ┃ 北 ┃ ┃\n" ); printf( "\t\t\t\t\t\t┃ ┗━━━━━┛ ┗━━━┛ ┃\n" ); printf( "\t\t\t\t\t\t┗━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n" ); } void Outputplace() /* 输出校园景点名称 */ { printf( "\t\t\t\t\t\t┏━━━━━━━━━━━━━━━━━━━━━━━━━┓\n" ); printf( "\t\t\t\t\t\t┃ 西安邮电学院学校景点一览表 ┃\n" ); printf( "\t\t\t\t\t\t┣━━━━━━━━━━━━┳━━━━━━━━━━━━┫\n" ); printf( "\t\t\t\t\t\t┃1.学校正门 ┃2.行政楼 ┃\n" ); printf( "\t\t\t\t\t\t┣━━━━━━━━━━━━╋━━━━━━━━━━━━┫\n" ); printf( "\t\t\t\t\t\t┃3.教学楼 ┃4.喷泉 ┃\n" ); printf( "\t\t\t\t\t\t┣━━━━━━━━━━━━╋━━━━━━━━━━━━┫\n" ); printf( "\t\t\t\t\t\t┃5.实验楼 ┃6.大学生活动中心 ┃\n" ); printf( "\t\t\t\t\t\t┣━━━━━━━━━━━━╋━━━━━━━━━━━━┫\n" ); printf( "\t\t\t\t\t\t┃7.图书馆 ┃8.洗浴中心 ┃\n" ); printf( "\t\t\t\t\t\t┣━━━━━━━━━━━━╋━━━━━━━━━━━━┫\n" ); printf( "\t\t\t\t\t\t┃9.体育馆 ┃10.体育场 ┃\n" ); printf( "\t\t\t\t\t\t┣━━━━━━━━━━━━╋━━━━━━━━━━━━┫\n" ); printf( "\t\t\t\t\t\t┃11.土操场 ┃12.篮球场 ┃\n" ); printf( "\t\t\t\t\t\t┣━━━━━━━━━━━━╋━━━━━━━━━━━━┫\n" ); printf( "\t\t\t\t\t\t┃13.美食广场 ┃14.旭日苑 ┃\n" ); printf( "\t\t\t\t\t\t┗━━━━━━━━━━━━┻━━━━━━━━━━━━┛\n" ); } void SearchPlace() /* 查询景点信息 */ { int i, num; char c = 'y'; while ( c == 'y' ) { system( "cls" ); Outputplace(); printf( "\t\t\t\t\t\t请输入您要查找的景点编号:" ); scanf( "%d", &num ); getchar(); system( "cls" ); if ( num > 0 && num <= G.vexnum ) /* 判定信息输入正确 */ { for ( i = 1; i <= G.vexnum; i++ ) if ( num == G.vertex[i].number ) { printf( "\n\t\t\t\t\t\t景点编号:%d\n", i ); printf( "\t\t\t\t\t\t景点名称:%s\n", G.vertex[i].name ); printf( "\t\t\t\t\t\t景点简介:%s\n\n", G.vertex[i].info ); } }else printf( "\t\t\t\t\t\t信息输入有误!\n" ); num = 0; printf( "\n\t\t\t\t\t\t是否继续查询景点信息(y/n):" ); c = getchar(); getchar(); } system( "cls" ); } void SearchPath() /* 查询最短路径 */ { int i, j; char c = 'y'; while ( c == 'y' ) { system( "cls" ); Outputplace(); printf( "\n\n\t\t\t\t\t\t初始景点编号(1->14):" ); scanf( "%d", &i ); printf( "\t\t\t\t\t\t最终景点编号(1->14):" ); scanf( "%d", &j ); getchar(); if ( i > G.vexnum || i <= 0 || j > G.vexnum || j < 0 || i == j ) printf( "\t\t\t\t\t\t输入信息错误!\n\n" ); else{ Shortpath( i ); output( i, j ); } printf( "\n\t\t\t\t\t\t是否继续查询最短路径(y/n):" ); c = getchar(); getchar(); } system( "cls" ); } void Shortpath( int num ) /* 迪杰斯特拉算法最短路径 */ { int v, w, i, t; /* i、w和v为计数变量 */ int final[NUM]; /* 标志数组、用来存放顶点的信息 */ int min; /* 记录权值、最终输出路径 */ for ( v = 0; v < NUM; v++ ) { final[v] = 0; /* 假设从顶点num到顶点v没有最短路径 */ D[v] = G.arc[num][v].length; /* 将num到其余顶点的最短路径长度初始化为权值 */ for ( w = 0; w < NUM; w++ ) path[v][w] = 0; /* 初始化从v到w的路径值 */ if ( D[v] < 20000 ) /* 存在路径 */ { path[v][num] = 1; /* 存在标志置为一 */ path[v][v] = 1; /* 自身到自身 */ } } D[num] = 0; /* 初始化新路径 */ final[num] = 1; /* 初始化num顶点属于final集合 */ /* 开始主循环,每一次求得num到某个顶点的最短路径,并将其加入到final集合 */ for ( i = 0; i < NUM; ++i ) /* 其余G.vexnum-1个顶点 */ { min = MAX; /* 当前所知离顶点num的最近距离 */ for ( w = 0; w < NUM; ++w ) if ( !final[w] ) /* w顶点在v-s中 */ if ( D[w] < min ) /* w顶点离num顶点更近 */ { v = w; min = D[w]; } final[v] = 1; /* 离num顶点更近的v加入到s集合 */ for ( w = 0; w < NUM; ++w ) /* 更新当前最短路径极其距离 */ if ( !final[w] && ( (min + G.arc[v][w].length) < D[w]) ) /*不在s集合,并且比以前所找到的路径都短就更新当前路径 */ { D[w] = min + G.arc[v][w].length; /* 更新路径 */ for ( t = 0; t < NUM; t++ ) path[w][t] = path[v][t]; path[w][w] = 1; } } } void output( int sight1, int sight2 ) /* 输出函数 */ { int a, b, c, d, q = 0; a = sight2; /* 将景点二赋值给a */ if ( a != sight1 ) /* 如果景点二不和景点一输入重合,则进行... */ { printf( "\t\t\t\t\t\t从%s到%s的最短路径是:\n\n\t\t\t\t\t", G.vertex[sight1].name, G.vertex[sight2].name ); /* 输出提示信息 */ /* 输出sight1到sight2的最短路径长度,存放在D[]数组中 */ printf( "\t%s", G.vertex[sight1].name ); /* 输出景点一的名称 */ d = sight1; /* 将景点一的编号赋值给d */ for ( c = 0; c < NUM; ++c ) { gate:; /* 标号,可以作为goto语句跳转的位置 */ path[a][sight1] = 0; for ( b = 0; b < NUM; b++ ) { if ( G.arc[d][b].length < MAX && path[a][b] ) /* 如果景点一和它的一个临界点之间存在路径且最短路径 */ { printf( "--->%s", G.vertex[b].name ); /* 输出此节点的名称 */ q = q + 1; /* 计数变量加一,满8控制输出时的换行 */ path[a][b] = 0; d = b; /* 将b作为出发点进行下一次循环输出,如此反复 */ if ( q % 14 == 0 ) printf( "\n" ); goto gate; } } } printf( "\n\n\t\t\t\t\t\t最短距离为 %dm.\n\n\t", D[a] ); } } /*void AddPlace()//增加景点函数 * * * { * * * int i,j,k; * * * char c='y'; * * * while(c=='y') * * * { * * * system("cls"); * * * printf("\n\n\t\t\t\t\t\t输入要添加的景点编号:"); * * * scanf("%d",&i); * * * if(i>G.vexnum) * * * { * * * i-=1; * * * printf("\n\n\t\t\t\t\t\t输入要添加的景点名称:"); * * * * * * * G.vertex[i].name=(char*)malloc(50);//申请节点 * * * flushall(); * * * gets(G.vertex[i].name); * * * printf("\n\n\t\t\t\t\t\t输入节点的简介:\n\n\t\t\t\t\t\t"); * * * G.vertex[i].info=(char*)malloc(1000);//申请节点 * * * flushall(); * * * * * * gets(G.vertex[i].info); * * * printf("\n\n\t\t\t\t\t\t输入相邻的节点:");//相邻节点 * * * scanf("%d",&j); * * * printf("\n\n\t\t\t\t\t\t输入它的权值:");//赋权值 * * * scanf("%d",&k); * * * G.arc[i][j].length=G.arc[j][i].length=k; * * * printf("\n\n\t\t\t\t\t\t增加成功:\n\n\n\t\t\t\t\t\t按任意键继续……\n\n\n\t\t\t\t\t\t"); * * * getch(); * * * * * * } * * * else * * * { * * * printf("\n\n\t\t\t\t\t\t您输入的景点编号已经存在!\n"); * * * printf("\n\n\t\t\t\t\t\t按任意键继续……"); * * * c=getchar(); * * * getchar(); * * * } * * * * * * * * * } * * * system("cls"); * * * } * * * * * */ void main() { int x; system( "color 2B" ); system( "mode con: cols=250 lines=500" ); /* 调整屏幕显示大小 */ CreateGraph(); printf( " 欢迎使用西安邮电大学校园导游系统\n\n\n" ); while ( 1 ) { /* Map(); */ printf( "\n\n" ); printf( "\t\t\t┏━━━━━━━━━━┓\n" ); printf( "\t\t\t┃1. 校园全景浏览 ┃\n" ); printf( "\t\t\t┃2. 景点信息查询 ┃\n" ); printf( "\t\t\t┃3. 最短路径查询 ┃\n" ); printf( "\t\t\t┃0. 退出系统 ┃\n" ); printf( "\t\t\t┗━━━━━━━━━━┛\n" ); printf( "\n\t\请选择您需要的操作(0-4):" ); scanf( "%d", &x ); getchar(); switch ( x ) { case 1: system( "cls" ); printf( "\t\t\t\t\t\t\t校园全景浏览:" ); Map(); break; case 2: system( "cls" ); printf( "\t\t\t\t\t\t\t景点信息查询:" ); SearchPlace(); break; case 3: system( "cls" ); printf( "\t\t\t\t\t\t\t最短路径查询:" ); SearchPath(); break; case 0: printf( "\n\t\t\t\t\t\t\t" ); exit( 0 ); default: system( "cls" ); printf( "\t\t\t\t\t\t\t输入信息错误,请重新输入!\n" ); break; } } }