校园导游v1.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /**
  2. 问题描述:用无向网表示你所在学校的校园地点平面图,图中顶点表示主要地点,
  3. 存放地点的编号、名称、简介等信息,图中的边表示地点间的道路,存放路径长度等信息。
  4. 要求能够回答有关地点介绍、游览路径等问题。
  5. 基本要求:查询各地点的相关信息;
  6. 查询图中任意两个地点间的最短路径;
  7. 查询图中任意两个地点间的所有路径;增加、删除、更新有关地点和道路的信息。
  8. 选作内容:
  9. 1.求多个地点的最佳(最短)游览路径。
  10. 2.区分机动车道和人行道。
  11. 3.实现导游图的仿真界面。
  12. **/
  13. #include <iostream>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <iomanip>
  17. #include <stdlib.h>
  18. #include <math.h>
  19. #define INFINITY 65535 ///无穷大,即不相邻
  20. #define MAX_VERTEX_NUM 20 ///最大的顶点个数
  21. using namespace std;
  22. typedef int VRType;
  23. typedef char InfoType;
  24. typedef struct
  25. {
  26. int num;
  27. char name[20];
  28. char introduce[100];
  29. } VertexType;
  30. typedef struct ArcCell
  31. {
  32. VRType adj; ///距离
  33. InfoType *info;///边的信息
  34. } ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
  35. typedef struct
  36. {
  37. VertexType vex[MAX_VERTEX_NUM];///顶点向量
  38. AdjMatrix arcs; ///邻接矩阵
  39. int vexnum,arcnum; ///顶点数和边数
  40. } MGraph;
  41. void schoolmap()
  42. {
  43. printf(" 安科平面图 \n");
  44. printf(" *----------------------------------------------------------------------------*\n");
  45. printf(" | |西门| |\n");
  46. printf(" |----------------------------------------------------------------------------|\n");
  47. printf(" | *----------------* *-----------------* *--------------------------------* |\n");
  48. printf(" | | | | | | 生活区 (1) | |\n");
  49. printf(" | | 风 雨 | | | | *----* *----* *----* *----* | |\n");
  50. printf(" | | | | | | | 德 | | 德 | | 德 | | 德 | | |\n");
  51. printf(" | | 操 场 | | 球场 (2) | | | 馨 | | 馨 | | 馨 | | 馨 | | |\n");
  52. printf(" | | | | | | | 苑 | | 苑 | | 苑 | | 苑 | | |\n");
  53. printf(" | | (3) | | | | | 1 | | 2 | | 3 | | 4 | | |\n");
  54. printf(" | | | | | | *----* *----* *----* *----* | |\n");
  55. printf(" | *----------------* *-----------------* *--------------------------------* |\n");
  56. printf(" | ----------------------- *----------* |\n");
  57. printf(" | | 间 | 市 | 室 | | *------* | |\n");
  58. printf(" | | 空 | 超 | | | | B | | |\n");
  59. printf(" | | 创 | 苑 | | | | 园 | | |\n");
  60. printf(" | | 众 | 学 | 浴 | | | | | |\n");
  61. printf(" | | (4)| (5) |(6)| | | 味 | | |\n");
  62. printf(" | ----------------------- | | | | |\n");
  63. printf(" | *---------* | 知 | | |\n");
  64. printf(" | | *-------* | | |\n");
  65. printf(" | | | | | |\n");
  66. printf(" | | | 知味园A | | |\n");
  67. printf(" | *----------------------------------* | | | | |\n");
  68. printf(" | | *--------* *--------* *-------* | | *---------------* | |\n");
  69. printf(" | | | | | | | | | | (7) | |\n");
  70. printf(" | | | A | | B | | C | | *--------------------* |\n");
  71. printf(" | | | 楼 | | 楼 | | 楼 | | |\n");
  72. printf(" | | | 知 | | 知 | | 知 | | |\n");
  73. printf(" | | | 致 | | 致 | | 致 | | |\n");
  74. printf(" | | | | | | | | | |\n");
  75. printf(" | | *--------* *--------* *-------* | |\n");
  76. printf(" |-----* | (8) | *----------* |\n");
  77. printf(" | 门 | *-----------------------------------* | | |\n");
  78. printf(" | (11)| | 馆 | |\n");
  79. printf(" | | | 书 | |\n");
  80. printf(" | 南 | | 图 | |\n");
  81. printf(" |-----* *-------------------------------------* | (10) | |\n");
  82. printf(" | | (9) | *----------* |\n");
  83. printf(" | | *--------* *--------* *-------* | |\n");
  84. printf(" | | | | | | | | | |\n");
  85. printf(" | | | A | | B | | C | | |\n");
  86. printf(" | | | 楼 | | 楼 | | 楼 | | |\n");
  87. printf(" | | | 行 | | 行 | | 行 | | |\n");
  88. printf(" | | | 敏 | | 敏 | | 敏 | | |\n");
  89. printf(" | | | | | | | | | |\n");
  90. printf(" | | *--------* *--------* *-------* | | 东 门 | |\n");
  91. printf(" *------*-------------------------------------*--------*-----------*------------*\n");
  92. printf("\n");
  93. }
  94. void create(MGraph &g,VertexType site[])
  95. {
  96. int i,j;
  97. g.vexnum=11;
  98. g.arcnum=12;
  99. for(i=0; i<11; i++)
  100. g.vex[i]=site[i];
  101. for(i=0; i<g.vexnum; i++)
  102. for(j=0; j<g.vexnum; j++)
  103. g.arcs[i][j]= {INFINITY,NULL};
  104. g.arcs[0][1].adj=200;
  105. g.arcs[1][2].adj=150;
  106. g.arcs[2][3].adj=50;
  107. g.arcs[3][4].adj=100;
  108. g.arcs[4][5].adj=50;
  109. g.arcs[5][9].adj=300;
  110. g.arcs[6][7].adj=450;
  111. g.arcs[6][9].adj=500;
  112. g.arcs[0][4].adj=300;
  113. g.arcs[0][7].adj=250;
  114. g.arcs[9][10].adj=700;
  115. g.arcs[7][8].adj=20;
  116. for(i=0; i<g.vexnum; i++)
  117. for(j=0; j<g.vexnum; j++)
  118. g.arcs[j][i].adj= g.arcs[i][j].adj;
  119. }
  120. void output(MGraph g,int i)///根据序号i输出对应的地点的相关信息
  121. {
  122. printf("地点序号:%d\n",i);
  123. printf("地点名称:%s\n",g.vex[i-1].name);
  124. printf("地点简介:%s\n",g.vex[i-1].introduce);
  125. }
  126. void search(MGraph g)
  127. {
  128. int i;
  129. printf("请输入你想查找地点的序号:");
  130. scanf("%d",&i);
  131. output(g,i);
  132. }
  133. void Shortest_Path_Dijkstra(MGraph g,int v0,int P[][20],int D[20])
  134. {
  135. int v,w,i,j,final[20],min;
  136. for(v=0; v<g.vexnum; v++)
  137. {
  138. final[v]=0;
  139. D[v]=g.arcs[v0][v].adj;
  140. for(w=0; w<g.vexnum; w++)
  141. P[v][w]=-1;
  142. if(D[v]<INFINITY)
  143. {
  144. P[v][0]=v0;
  145. P[v][1]=v;
  146. }
  147. }
  148. D[v0]=0;
  149. final[v0]=1;
  150. for(i=1; i<g.vexnum; i++)
  151. {
  152. min=INFINITY;
  153. for(w=0; w<g.vexnum; w++)
  154. if(!final[w]&&D[w]<min)
  155. {
  156. v=w;
  157. min=D[w];
  158. }
  159. final[v]=1;
  160. for(w=0; w<g.vexnum; w++)
  161. if(!final[w]&&(min+g.arcs[v][w].adj<D[w]))
  162. {
  163. D[w]=min+g.arcs[v][w].adj;
  164. for(j=0; j<g.vexnum; j++)
  165. {
  166. P[w][j]=P[v][j];
  167. if(P[w][j]==-1)///在p[w][]第一个等于-1的地方加上顶点w
  168. {
  169. P[w][j]=w;
  170. break;
  171. }
  172. }
  173. }
  174. }
  175. }
  176. void ShortestPath_FLOYD(MGraph g, int P[20][20][20], int D[][20])
  177. {
  178. int u,v,w,i,j;
  179. for(v=0; v<g.vexnum; v++)
  180. for(w=0; w<g.vexnum; w++)
  181. {
  182. D[v][w]=g.arcs[v][w].adj;
  183. for(u=0; u<g.vexnum; u++)
  184. P[v][w][u]=-1;
  185. if(D[v][w]<INFINITY)
  186. {
  187. P[v][w][0]=v;
  188. P[v][w][1]=w;
  189. }
  190. }
  191. for(u=0; u<g.vexnum; u++)
  192. for(v=0; v<g.vexnum; v++)
  193. for(w=0; w<g.vexnum; w++)
  194. if(D[v][u]<INFINITY&&D[u][w]<INFINITY&&D[v][u]+D[u][w]<D[v][w])
  195. {
  196. ///更新D
  197. D[v][w]=D[v][u]+D[u][w];
  198. ///更新p,从v到w的路径是从v到u,再从u到w的所有路径
  199. for(i=0; i<g.vexnum; i++)
  200. {
  201. if(P[v][u][i]!=-1)
  202. P[v][w][i]=P[v][u][i];
  203. else
  204. break;
  205. }
  206. for(j=1; j<g.vexnum; j++) ///注意:这里j从1开始而不是从0开始,因为从v到u的路径最后一个顶点是u, 而从u到w的路径第一个顶点是u,只需打印u一次即可。
  207. {
  208. if(P[u][w][j]!=-1)
  209. P[v][w][i++]=P[u][w][j];
  210. else
  211. break;
  212. }
  213. }
  214. }
  215. void update(MGraph &g)
  216. {
  217. int i;
  218. printf("请输入你想查找的地点的序号:");
  219. scanf("%d",&i);
  220. if(i>=1&&i<=11)
  221. {
  222. printf("请输入新的地点名称:");
  223. scanf("%s",g.vex[i-1].name);
  224. printf("请输入新的地点名称简介:");
  225. scanf("%s",g.vex[i-1].introduce);
  226. }
  227. }
  228. void add_arc(MGraph &g)
  229. {
  230. int v1,v2,n;
  231. printf("请输入你想增加的边两端的顶点序号:");
  232. printf("请输入第一个顶点号:");
  233. scanf("%d",&v1);
  234. printf("请输入第二个顶点号:");
  235. scanf("%d",&v2);
  236. if(g.arcs[v1-1][v2-1].adj==INFINITY)
  237. {
  238. printf("请输入两点之间的距离:");
  239. scanf("%d",&g.arcs[v1-1][v2-1].adj);
  240. g.arcs[v2-1][v1-1].adj=g.arcs[v1-1][v2-1].adj;
  241. printf("增加成功!嘤嘤嘤^_^\n");
  242. }
  243. else
  244. {
  245. LL0:
  246. printf("这两点已经有路径存在了,你想要修改它吗?想的话请按1,不想请按2:\n");
  247. scanf("%d",&n);
  248. if(n==1)
  249. {
  250. printf("请输入两点之间的新的距离:");
  251. scanf("%d",&g.arcs[v1-1][v2-1].adj);
  252. g.arcs[v2-1][v1-1].adj=g.arcs[v1-1][v2-1].adj;
  253. printf("修改成功!嘤嘤嘤^-^\n");
  254. }
  255. else if(n==2)
  256. {
  257. printf("增加失败,嘤嘤嘤T_T\n");
  258. }
  259. else
  260. {
  261. printf("你的输入有误,请重新输入!嘤嘤嘤qwq\n");
  262. goto LL0;
  263. }
  264. }
  265. }
  266. void delete_arc(MGraph &g)
  267. {
  268. int v1,v2;
  269. printf("请输入你想删除的边两端的顶点序号:\n");
  270. printf("请输入第一个顶点号:\n");
  271. scanf("%d",&v1);
  272. printf("请输入第二个顶点号:\n");
  273. scanf("%d",&v2);
  274. if(g.arcs[v1-1][v2-1].adj!=INFINITY)
  275. {
  276. g.arcs[v1-1][v2-1].adj=g.arcs[v2-1][v1-1].adj=INFINITY;
  277. printf("删除成功!嘤嘤嘤^_^\n");
  278. }
  279. else
  280. {
  281. printf("删除失败!这两个点之间本来就没有直接通路,你还删它干嘛?!嘤嘤嘤qwq\n");
  282. }
  283. }
  284. void display_num(MGraph g)
  285. {
  286. int i;
  287. printf("<地点序号> <地点名称>\n");
  288. for(i=0; i<g.vexnum; i++)
  289. {
  290. printf("%5d %s\n",g.vex[i].num,g.vex[i].name);
  291. }
  292. }
  293. void display_all(MGraph g)
  294. {
  295. int i;
  296. printf("<地点序号> <地点名称> <地点简介>\n");
  297. for(i=0; i<g.vexnum; i++)
  298. {
  299. printf("%5d %s %s\n",g.vex[i].num,g.vex[i].name,g.vex[i].introduce);
  300. }
  301. }
  302. void menu()
  303. {
  304. printf("\n************************************************************\n");
  305. printf("*** 0.大安科全景地图 ***\n");
  306. printf("*** 1.显示所有地点的序号 ***\n");
  307. printf("*** 2.查询所有地点的信息 ***\n");
  308. printf("*** 3.查询某个地点的具体信息 ***\n");
  309. printf("*** 4.查询某个地点到其他地点的最短路径 ***\n");
  310. printf("*** 5.输出任意两个地点之间的最短路径 ***\n");
  311. printf("*** 6.增加某一条边 ***\n");
  312. printf("*** 7.删除某一条边 ***\n");
  313. printf("*** 8.修改某一条边 ***\n");
  314. printf("*** 9.退出系统 ***\n");
  315. printf("************************************************************\n");
  316. }
  317. int main()
  318. {
  319. int v1,v2,P1[20][20],P2[20][20][20],D1[20],D2[20][20],i,j,k;
  320. MGraph g;
  321. VertexType site[11]=
  322. {
  323. {1,"生活区"," 一大群孩子的老巢"},
  324. {2,"球场"," 锻炼身体、休闲娱乐的地方"},
  325. {3,"风雨操场","情侣们秀恩爱的最佳去处"},
  326. {4,"众创空间","集合广播台等高大尚的工作的地方"},
  327. {5,"学苑超市","一个坑钱的地方,thing贼贵"},
  328. {6,"浴室"," 让你出淤泥而不染的地方"},
  329. {7,"知味园"," 小而拥挤、人流量te多还难吃的就餐地方"},
  330. {8,"致知楼"," 结合上课和办公与一体的高端教学楼"},
  331. {9,"敏行楼"," 夏天不热、冬天不冷的实验楼,也是报告厅所在地"},
  332. {10,"图书馆"," 还在建设中,想进去都进不去"},
  333. {11,"学校南门","学校正门,学校的门面,然而基本没开过"}
  334. };
  335. create(g,site);
  336. printf(" 欢迎来到安科地图导航! \n");
  337. LL1:
  338. menu();
  339. printf("please intput your choose:");
  340. scanf("%d",&i);
  341. switch(i)
  342. {
  343. case 0:
  344. schoolmap();
  345. goto LL1;
  346. break;
  347. case 1:
  348. display_num(g);
  349. goto LL1;
  350. break;
  351. case 2:
  352. display_all(g);
  353. goto LL1;
  354. break;
  355. case 3:
  356. search(g);
  357. goto LL1;
  358. break;
  359. case 4:
  360. printf("请输入地点的序号:\n");
  361. scanf("%d",&k);
  362. Shortest_Path_Dijkstra(g,k-1,P1,D1);
  363. for(i=1; i<g.vexnum; i++)
  364. {
  365. printf("%d号(%s)到%d号(%s):",k,g.vex[k-1].name,i+1,g.vex[i].name);
  366. for(j=0; P1[i][j]!=-1; j++)
  367. printf("%d号(%s) ",P1[i][j]+1,g.vex[P1[i][j]].name);
  368. printf("\n距离为:%d\n",D1[i]);
  369. puts("");
  370. }
  371. goto LL1;
  372. break;
  373. case 5:
  374. ShortestPath_FLOYD(g,P2,D2);
  375. for(i=0; i<g.vexnum; i++)
  376. {
  377. for(int j=0; j<g.vexnum; j++)
  378. {
  379. if(i!=j)
  380. {
  381. if(D2[i][j]!=INFINITY)
  382. {
  383. cout<<g.vex[i].name<<"到"<<g.vex[j].name<<"的最短长度为:"<<setw(5)<<D2[i][j]<<", 最短路径为:";
  384. for(int k=0; k<g.vexnum; k++)
  385. {
  386. if(P2[i][j][k]!=-1)
  387. cout<<g.vex[P2[i][j][k]].name<<" ";
  388. else
  389. break;
  390. }
  391. puts("");
  392. }
  393. else
  394. cout<<g.vex[i].name<<"到"<<g.vex[j].name<<"不可达"<<endl;
  395. }
  396. }
  397. puts("");
  398. }
  399. goto LL1;
  400. break;
  401. case 6:
  402. add_arc(g);
  403. goto LL1;
  404. break;
  405. case 7:
  406. delete_arc(g);
  407. goto LL1;
  408. break;
  409. case 8:
  410. update(g);
  411. goto LL1;
  412. break;
  413. case 9:
  414. printf("下次再来玩呦,嘤嘤嘤^_^!\n");
  415. exit(0);
  416. goto LL1;
  417. break;
  418. default:
  419. printf("你的输入有误,请重新输入!嘤嘤嘤qwq\n");
  420. goto LL1;
  421. break;
  422. }
  423. }