运行效果:
说明:
由于当年还不会使用多线程,所以很多获取用户点击的地方都是使用循环实现的。。。CPU占用率会比较高。
代码:
//校园导游系统.cpp
1 #include <graphics.h> 2 #include <conio.h> 3 #include <stdio.h> 4 #include <io.h> 5 #include <stdlib.h> 6 #include <string> 7 #include <iostream> 8 #include <math.h> 9 #include <fstream> 10 #include "Stack.h" 11 #include "functions.h" 12 #include "Graph_List.h" 13 #define WIDTH (1000+(LEFTBORDER*2)) 14 #define HEIGHT (574+TOPBORDER+LEFTBORDER) 15 #define UP 72 16 #define DOWN 80 17 #define LEFT 75 18 #define RIGHT 77 19 #define BACKGROUND "background.jpg" 20 #define BKCOLOR RGB(240,240,240) //原RGB(240,240,240) 21 #define SELECTCOLOR RGB(255,0,0) //原RED 22 #define TEXTCOLOR RGB(7,102,198)//GREEN// //原BLUE 23 #define MENUCOLOR RGB(208,161,227)//RGB(77,197,131)//RGB(112,112,112)//RGB(117,75,144)//RGB(7,102,198) //原GREEN 24 #define CheckCancel if(iscancel){return -1;} 25 using namespace std; 26 Graph_List graph; 27 int choose; 28 int menunum = 11; 29 int menutop1 = 10; 30 int menutop = (menutop1 + 3); 31 #define left (LEFTBORDER) 32 int menuwidth = ((WIDTH - 2 * LEFTBORDER) / (menunum )); 33 int menuheight = 30; 34 int GetChoose(); 35 int FrontMenu(Graph_List &graph ); 36 int ShowAllVertex(Graph_List &graph); 37 int ShowAllPath(Graph_List &graph); 38 int printroad(int dx, int dy, int sx, int sy) { 39 LINESTYLE linestyle; 40 getlinestyle(&linestyle); 41 setlinestyle(PS_SOLID,3,NULL,0); 42 setlinecolor(BLUE); 43 line(sx,sy,dx,dy); 44 setlinestyle(&linestyle); 45 double x1 = (sx + dx) / 2; 46 double y1 = (sy + dy) / 2; 47 double x2 = ((3.0 / 8.0) * sx + (5.0 / 8.0) * dx); 48 double y2 = ((3.0 / 8.0) * sy + (5.0 / 8.0) * dy); 49 //double x1=sx,x2=(sx+dx)/2,y1=sy,y2=(sy+dy)/2; 50 double k1 = (y2 - y1) / (x2 - x1); 51 double k2 = (-1) / k1; 52 double delta = 1600; //=(y2-y1)*(y2-y1)+(x2-x1)*(x2-x1); 53 double a = sqrt((delta / 16) / (1 + k2 * k2)); 54 double b = a * fabs(k2); 55 if(((x1 > x2) && (y1 < y2)) || ((x1 < x2) && (y1 > y2))) { 56 } else { 57 b = -1 * b; 58 } 59 if(x1 == x2) { 60 a = 5; 61 b = 0; 62 } 63 if(y1 == y2) { 64 a = 0; 65 b = 3; 66 } 67 POINT pts[] = { {x1, y1}, {x2 + a, y2 + b}, {(x1 + x2) / 2, (y1 + y2) / 2}, }; 68 POINT pts1[] = { {x1, y1}, {x2 * 2 - (x2 + a), y2 * 2 - (y2 + b)}, {(x1 + x2) / 2, (y1 + y2) / 2}, }; 69 setfillcolor(BLUE); 70 solidpolygon(pts1, 3); 71 solidpolygon(pts, 3); 72 return 0; 73 } 74 int GetMouseXY(int& mousex,int& mousey) { 75 MOUSEMSG temp; 76 temp.mkLButton = false; 77 bool kick = false; 78 while(!kick) { 79 // if(MouseHit()) { 80 temp = GetMouseMsg(); 81 FlushMouseMsgBuffer(); 82 if(temp.mkLButton == false) { 83 mousex = temp.x; 84 mousey = temp.y; 85 } 86 else { 87 kick = temp.mkLButton ; 88 } 89 // } 90 } 91 return 0; 92 } 93 int AddVertex(Graph_List &graph) { 94 LOGFONT font; 95 gettextstyle(&font); 96 settextstyle(10, 0, _T("宋体")); 97 BeginBatchDraw(); 98 setlinecolor(GREEN); 99 for(int lx = LEFTBORDER; lx <= WIDTH; lx += 50) { 100 //outtextxy(lx, TOPBORDER - 10, &int_to_str(lx - LEFTBORDER)[0]); 101 line(lx, TOPBORDER, lx, HEIGHT - LEFTBORDER); 102 } 103 for(int ly = TOPBORDER; ly <= HEIGHT - LEFTBORDER; ly += 50) { 104 //outtextxy(10, ly - 5, &int_to_str(ly - TOPBORDER)[0]); 105 line(LEFTBORDER, ly, WIDTH - LEFTBORDER, ly); 106 } 107 FlushBatchDraw(); 108 setlinecolor(MENUCOLOR); 109 settextstyle(&font); 110 ::MessageBox(GetHWnd(), "请在您要添加景点的位置点击", "添加景点", MB_OK); 111 int mousex,mousey; 112 GetMouseXY(mousex,mousey); 113 char name[30]; 114 bool iscancel = false; 115 iscancel = !InputBox(&(name[0]), 30, "输入名称" , "添加景点", "0", 0, 0, 0); 116 CheckCancel 117 char describe[1000]; 118 iscancel = !InputBox(&(describe[0]), 1000, "输入简介:(按Ctrl+Enter确认输入)" , "添加景点", "0", 0, 10, 0); 119 CheckCancel 120 char mark[10]; 121 int marki; 122 while(1) { 123 iscancel = !InputBox(&(mark[0]), 10, "输入代号" , "添加景点", 0, 0, 0, 0); 124 CheckCancel 125 marki = str_to_num(mark); 126 if(marki > 0 && graph.GetIndex(marki) == -1) { 127 break; 128 } 129 ::MessageBox(GetHWnd(), "此代号已存在,请重输", "添加景点", MB_OK); 130 } 131 string namestr = "", describestr = ""; 132 graph.InsertVertex((string)(namestr + name), (string)(describestr + describe), marki, mousex, mousey); 133 ::MessageBox(GetHWnd(), "添加成功", "添加景点", MB_OK); 134 return 0; 135 } 136 int AddPath(Graph_List &graph) { 137 bool iscancel = false; 138 int v1, v2; 139 string source = "0000000000", destination = "0000000000", weightstr = "0000000000"; 140 while(1) { 141 iscancel = !InputBox(&(source[0]), 10, "输入起点代号" , "添加边", "0", 0, 0, 0); 142 CheckCancel 143 v1 = str_to_num(source); 144 if(graph.GetIndex(v1) != -1) { 145 break; 146 } 147 ::MessageBox(GetHWnd(), "该位置不存在,请重输", "添加边", MB_OK); 148 } 149 while(1) { 150 iscancel = !InputBox(&(destination[0]), 10, "输入终点代号", "添加边", "0", 0, 0, 0); 151 CheckCancel 152 v2 = str_to_num(destination); 153 if(graph.GetIndex(v2) != -1) { 154 break; 155 } 156 ::MessageBox(GetHWnd(), "该位置不存在,请重输", "添加边", MB_OK); 157 } 158 double dx = graph.GetHead()[graph.GetIndex(v2)].GetX(); 159 double sx = graph.GetHead()[graph.GetIndex(v1)].GetX(); 160 double dy = graph.GetHead()[graph.GetIndex(v2)].GetY(); 161 double sy = graph.GetHead()[graph.GetIndex(v1)].GetY(); 162 double weight = (double)sqrt(((dx - sx) * (dx - sx) + (dy - sy) * (dy - sy)) / 24250.0) * 300.0; 163 int retop=graph.InsertEdge(graph.GetIndex(v1), graph.GetIndex(v2), weight); 164 if(retop==-3){::MessageBox(GetHWnd(), "起点与终点相同!", "添加边", MB_OK);return -3;} 165 if(retop==-4){::MessageBox(GetHWnd(), "边已存在!", "添加边", MB_OK);return -4;} 166 ::MessageBox(GetHWnd(), "添加成功", "添加边", MB_OK); 167 return 0; 168 } 169 int DeleteVertex(Graph_List &graph){ 170 bool iscancel = false; 171 char v[10]; 172 int v1; 173 while(1) { 174 iscancel = !InputBox(&(v[0]), 10, "输入代号" , "删除景点", "0", 0, 0, 0); 175 CheckCancel 176 v1 = str_to_num(v); 177 178 if(graph.GetIndex(v1)!= -1) { 179 break; 180 } 181 ::MessageBox(GetHWnd(), "此代号不存在,请重输", "删除景点", MB_OK); 182 } 183 graph.DeleteVertex(graph.GetIndex(v1)); 184 return 0; 185 } 186 int DeletePath(Graph_List &graph) { 187 bool iscancel = false; 188 int v1, v2; 189 string source = "0000000000", destination = "0000000000"; 190 while(1) { 191 iscancel = !InputBox(&(source[0]), 10, "输入起点代号" , "删除边", "0", 0, 0, 0); 192 CheckCancel 193 v1 = str_to_num(source); 194 if(graph.GetIndex(v1) != -1) { 195 break; 196 } 197 ::MessageBox(GetHWnd(), "该位置不存在,请重输", "删除边", MB_OK); 198 } 199 while(1) { 200 iscancel = !InputBox(&(destination[0]), 10, "输入终点代号", "删除边", "0", 0, 0, 0); 201 CheckCancel 202 v2 = str_to_num(destination); 203 if(graph.GetIndex(v2) != -1) { 204 break; 205 } 206 ::MessageBox(GetHWnd(), "该位置不存在,请重输", "删除边", MB_OK); 207 } 208 int retop=graph.DeleteEdge(graph.GetIndex(v1), graph.GetIndex(v2)); 209 if(retop==-1){::MessageBox(GetHWnd(), "边不存在!", "删除边", MB_OK);return -1;} 210 211 ::MessageBox(GetHWnd(), "删除成功", "删除边", MB_OK); 212 return 0; 213 } 214 int DrawShortestPath(Graph_List &graph, int v1, int v2) { 215 Vertex *Head = graph.GetHead(); 216 217 int *path = new int [graph.NumberOfVertices()]; 218 graph.DShortestPath(v1, path); 219 LStack<int > stack; 220 //stack.Push(v2); 221 if(path[v2] == -1) { 222 ::MessageBox(GetHWnd(), "*** 无路径 ***", "查询路径", MB_OK); 223 return -1; 224 } 225 int i = v2; 226 while(i != path[v1]) { 227 stack.Push(i); 228 i = path[i]; 229 } 230 delete []path; 231 //stack.Push(v1); 232 int temp = v1, temppre = v1, length = 0; 233 string pathstr,tempstr; 234 BeginBatchDraw(); 235 while(!stack.IsEmpty()) { 236 stack.Pop(temp); 237 printroad(Head[temppre].GetX(), Head[temppre].GetY(), Head[temp].GetX(), Head[temp].GetY()); 238 int pathweight=graph.GetWeight(temppre, temp); 239 length += pathweight; 240 tempstr=tempstr+"从"+int_to_str(Head[temppre].GetMark())+"到"+int_to_str(Head[temp].GetMark())+" : "+int_to_str(pathweight)+" 米"+"\n"; 241 temppre = temp; 242 } 243 244 FlushBatchDraw(); 245 setbkcolor(BKCOLOR); 246 settextcolor(TEXTCOLOR); 247 string str = "最短路径长度为:"; 248 str = str + int_to_str(length) + " 米\n"+"步行所需时间:"+int_to_str(length/90)+"分钟\n"; 249 str+=tempstr; 250 ::MessageBox(GetHWnd(), &str[0], "查询路径", MB_OK); 251 return 0; 252 } 253 int FindPath(Graph_List &graph) { 254 bool iscancel = false; 255 int v1, v2; 256 string source = "0000000000", destination = "0000000000"; 257 while(1) { 258 iscancel = !InputBox(&(source[0]), 10, "输入起点代号" , "查询路径", "0", 0, 0, 0); 259 CheckCancel 260 v1 = str_to_num(source); 261 if(graph.GetIndex(v1) != -1) { 262 break; 263 } 264 ::MessageBox(GetHWnd(), "该位置不存在,请重输", "查询路径", MB_OK); 265 } 266 while(1) { 267 iscancel = !InputBox(&(destination[0]), 10, "输入终点代号", "查询路径", "0", 0, 0, 0); 268 CheckCancel 269 v2 = str_to_num(destination); 270 if(graph.GetIndex(v2) != -1) { 271 break; 272 } 273 ::MessageBox(GetHWnd(), "该位置不存在,请重输", "查询路径", MB_OK); 274 } 275 DrawShortestPath(graph, graph.GetIndex(v1), graph.GetIndex(v2)); 276 return 0; 277 } 278 void ShowVertex(Graph_List &graph, int i) { 279 Vertex *Head = graph.GetHead(); 280 if(i < 0 || i > graph.NumberOfVertices() - 1) { 281 ::MessageBox(GetHWnd(), "查询位置不存在", "景点查询", MB_OK); //GetHWnd()获得窗口句柄 282 return ; 283 } 284 string str = "代号:" +int_to_str(Head[i].GetMark()) + "\n" + "简介: " + Head[i].GetDescribe(); 285 str = "名称:" + Head[i].GetVerName() + "\n" + str; 286 ::MessageBox(GetHWnd(), &str[0], "景点查询", MB_OK); //GetHWnd()获得窗口句柄 287 } 288 int ModifyMenu() { 289 int choose1 = 1; 290 char temp = 0, key; 291 while(temp != '\r') { 292 if(kbhit()) { 293 key = getch(); 294 fflush(stdin); 295 switch(key) { 296 case UP: { 297 choose1--; 298 }; 299 break; 300 case DOWN: { 301 choose1++; 302 }; 303 } 304 } 305 if(choose1 == 6) { 306 choose1 = 5; 307 } 308 if(choose1 == 0) { 309 choose1 = 1; 310 } 311 cleardevice(); 312 outtextxy((WIDTH / 2) - 80, 120, "修改景点"); 313 outtextxy((WIDTH / 2) - 180, 230, "按↑和↓选择选项"); 314 outtextxy((WIDTH / 2) - 180, 250, "按ENTER键确定选择"); 315 outtextxy(300, 300, "请选择选项:"); 316 outtextxy(420, 350, "修改名称"); 317 outtextxy(420, 380, "修改简介"); 318 outtextxy(420, 410, "修改代号"); 319 outtextxy(420, 440, "修改坐标"); 320 outtextxy(420, 470, "返回"); 321 outtextxy(390, 350 + (choose1 - 1) * 30, "→"); 322 FlushBatchDraw(); 323 temp = getch(); 324 } 325 return choose1; 326 } 327 int ModifyVertex(Graph_List &graph) { 328 bool iscancel = false; 329 int v1; 330 char v1str[10] = {'a'}; 331 while(1) { 332 iscancel = !InputBox(&(v1str[0]), 10, "输入代号" , "修改景点", "0", 0, 0, 0); 333 CheckCancel 334 v1= str_to_num(v1str); 335 if(graph.GetIndex(v1) != -1) { 336 break; 337 } 338 ::MessageBox(GetHWnd(), "该位置不存在,请重输", "修改景点", MB_OK); 339 } 340 int v=graph.GetIndex(v1); 341 Vertex *Head = graph.GetHead(); 342 string name=Head[v].GetVerName(); 343 string describe=Head[v].GetDescribe(); 344 int marki=Head[v].GetMark(),x=Head[v].GetX()-LEFTBORDER,y=Head[v].GetY()-TOPBORDER; 345 bool isreturn = false; 346 while(!isreturn ) { 347 int in = ModifyMenu(); 348 switch(in) { 349 case 1: { 350 iscancel = !InputBox(&(name[0]), 30, "输入名称" , "修改景点", "0", 0, 0, 0); 351 CheckCancel 352 }; 353 break; 354 case 2: { 355 iscancel = !InputBox(&(describe[0]), 1000, "输入简介:(按Ctrl+Enter确认输入)" , "修改景点", "0", 0, 10, 0); 356 CheckCancel 357 }; 358 break; 359 case 3: { 360 char mark[10]; 361 while(1) { 362 iscancel = !InputBox(&(mark[0]), 10, "输入代号" , "修改景点", 0, 0, 0, 0); 363 CheckCancel 364 marki = str_to_num(mark); 365 if(marki > 0 && (marki == Head[v].GetMark() || graph.GetIndex(marki) == -1)) { 366 break; 367 } 368 ::MessageBox(GetHWnd(), "输入有误或代号已存在,请重输", "修改景点", MB_OK); 369 } 370 }; 371 break; 372 case 4: { 373 char xstr[10], ystr[10]; 374 while(1) { 375 iscancel = !InputBox(&(xstr[0]), 10, "输入X坐标" , "修改景点", "0", 0, 0, 0); 376 CheckCancel 377 x = str_to_num(xstr); 378 if(x > 0 && x < WIDTH) { 379 break; 380 } 381 ::MessageBox(GetHWnd(), "您所输入的坐标不在图像范围内", "修改景点", MB_OK); 382 } 383 while(1) { 384 iscancel = !InputBox(&(ystr[0]), 10, "输入Y坐标" , "修改景点", "0", 0, 0, 0); 385 CheckCancel 386 y = str_to_num(ystr); 387 if(y > 0 && y < HEIGHT) { 388 break; 389 } 390 ::MessageBox(GetHWnd(), "您所输入的坐标不在图像范围内", "修改景点", MB_OK); 391 } 392 }; 393 break; 394 case 5: { 395 graph.ModifyVertex(v, name,describe, marki, x, y); 396 ShowVertex(graph, v); 397 isreturn = true; 398 }; 399 break; 400 default: 401 {}; 402 break; 403 } 404 } 405 return 0; 406 } 407 int ShowAllVertex(Graph_List &graph){ 408 Vertex *Head = graph.GetHead(); 409 //putimage(LEFTBORDER, TOPBORDER, graph.GetMap()); 410 setbkcolor(RGB(240, 240, 240)); 411 settextcolor(RED); 412 setfillcolor(RGB(255,0,0)); 413 LOGFONT font1; 414 gettextstyle(&font1); 415 settextstyle(font1.lfHeight - 2, 0, _T("宋体")); 416 for(int i = 0; i <= graph.NumberOfVertices() - 1; i++) { 417 int x = Head[i].GetX(), y = Head[i].GetY(); 418 string str = ""; 419 str += int_to_str(Head[i].GetMark()); 420 if(Head[i].GetVerName() != "*") 421 str = str + " " + Head[i].GetVerName(); 422 solidcircle(x,y,4); 423 outtextxy( x, y, &str[0]); 424 } 425 settextstyle(&font1); 426 FlushBatchDraw(); 427 return 0; 428 } 429 int ShowAllPath(Graph_List &graph) { 430 LINESTYLE linestyle; 431 getlinestyle(&linestyle); 432 setlinestyle(PS_SOLID,3,NULL,0); 433 setlinecolor(BLUE); 434 for(int i=0;i<=graph.NumberOfVertices()-1;i++){ 435 Edge* p=graph.GetHead()[i].Getadj(); 436 while(p!=NULL){ 437 line(graph.GetHead()[i].GetX(),graph.GetHead()[i].GetY(),graph.GetHead()[p->GetVerAdj()].GetX(),graph.GetHead()[p->GetVerAdj()].GetY()); 438 p=p->Getlink(); 439 } 440 } 441 setlinestyle(&linestyle); 442 FlushBatchDraw(); 443 return 0; 444 } 445 int FindMenu() { 446 int choose1 = 1; 447 char temp = 0, key; 448 while(temp != '\r') { 449 if(kbhit()) { 450 key = getch(); 451 fflush(stdin); 452 switch(key) { 453 case UP: { 454 choose1--; 455 }; 456 break; 457 case DOWN: { 458 choose1++; 459 }; 460 } 461 } 462 if(choose1 == 4) { 463 choose1 = 3; 464 } 465 if(choose1 == 0) { 466 choose1 = 1; 467 } 468 cleardevice(); 469 outtextxy((WIDTH / 2) - 80, 120, "查询景点"); 470 outtextxy((WIDTH / 2) - 180, 230, "按↑和↓选择选项"); 471 outtextxy((WIDTH / 2) - 180, 250, "按ENTER键确定选择"); 472 outtextxy(300, 300, "请选择选项:"); 473 outtextxy(420, 350, "按代号查询"); 474 outtextxy(420, 380, "按名称查询"); 475 outtextxy(420, 410, "返回"); 476 outtextxy(390, 350 + (choose1 - 1) * 30, "→"); 477 FlushBatchDraw(); 478 temp = getch(); 479 } 480 return choose1; 481 } 482 int FindVertex(Graph_List &graph) { 483 bool iscancel = false; 484 bool isreturn = false; 485 while(!isreturn ) { 486 int in = FindMenu(); 487 switch(in) { 488 case 1: { 489 char v1str[10] = {'a'}; 490 int v1; 491 iscancel = !InputBox(&(v1str[0]), 10, "输入代号" , "查询景点", "0", 0, 0, 0); 492 CheckCancel 493 v1 = str_to_num(v1str); 494 495 ShowVertex(graph, graph.GetIndex(v1)); 496 }; 497 break; 498 case 2: { 499 char v1str[10] = {'a'}; 500 string v1; 501 iscancel = !InputBox(&(v1str[0]), 10, "输入名称" , "查询景点", "0", 0, 0, 0); 502 CheckCancel 503 v1 = ""; 504 v1 += v1str; 505 ShowVertex(graph, graph.GetIndex(v1)); 506 }; 507 break; 508 case 3: { 509 510 isreturn = true; 511 }; 512 break; 513 default: 514 {}; 515 break; 516 } 517 } 518 return 0; 519 } 520 int Open(Graph_List &graph, bool isfirstopen) { 521 fstream filestr; 522 char mapname[256] = {'a'}; 523 if(isfirstopen) { 524 filestr.open ("map.txt"); 525 strcpy(mapname, "map.jpg"); 526 } else { 527 bool iscancel = false; 528 char filename[256] = {'a'}; 529 while(1) { 530 iscancel = !InputBox(&(filename[0]), 10, "输入文本文件名(不需输'.txt')" , "打开", "0", 0, 0, 0); 531 CheckCancel 532 strcat(filename, ".txt"); 533 filestr.open (filename); 534 if (filestr.is_open()) { 535 break; 536 } 537 ::MessageBox(GetHWnd(), "无此文件,请重输", "打开", MB_OK); 538 } 539 while(1) { 540 iscancel = !InputBox(&(mapname[0]), 10, "输入图片文件名(不需输'.jpg')" , "打开", "0", 0, 0, 0); 541 CheckCancel 542 strcat(mapname, ".jpg"); 543 if( (_access(mapname, 0 )) != -1 ) { 544 break; 545 } 546 ::MessageBox(GetHWnd(), "无此文件,请重输", "打开", MB_OK); 547 } 548 } 549 graph.graph_con(filestr, mapname); 550 filestr.close(); 551 putimage(LEFTBORDER, TOPBORDER, graph.GetMap()); 552 return 0; 553 } 554 int Save(Graph_List &graph) { 555 bool iscancel = false; 556 Vertex *Head = graph.GetHead(); 557 char filename[256] = {'a'}; 558 iscancel = !InputBox(&(filename[0]), 10, "输入文本文件名(不需输'.txt')" , "保存", "0", 0, 0, 0); 559 CheckCancel 560 strcat(filename, ".txt"); 561 graph.SaveFile(filename); 562 ::MessageBox(GetHWnd(), "保存成功", "保存", MB_OK); 563 return 0; 564 } 565 int GetChoose() { 566 FlushMouseMsgBuffer(); 567 MOUSEMSG temp; 568 temp.mkLButton = false; 569 bool kick = false; 570 while(!kick) { 571 // if(MouseHit()) { 572 temp = GetMouseMsg(); 573 FlushMouseMsgBuffer(); 574 if(temp.mkLButton == false) { 575 } else { 576 if(temp.y < menutop + menuheight &&temp. y > menutop) { 577 kick = true; 578 } 579 } 580 // } 581 } 582 choose = (temp.x - left) / menuwidth; 583 return 0; 584 } 585 int FrontMenu(Graph_List &graph) { 586 fflush(stdin); 587 settextcolor(TEXTCOLOR); 588 setfillcolor(BKCOLOR); 589 solidrectangle(5, TOPBORDER, WIDTH, HEIGHT); //以背景色刷新 590 setfillcolor(MENUCOLOR); 591 solidrectangle(5, 0, WIDTH - 5, menutop1); //画最上方的绿色条 592 putimage(LEFTBORDER, TOPBORDER, graph.GetMap()); 593 setfillcolor(BKCOLOR); 594 solidrectangle(LEFTBORDER, menutop + textheight('a'), WIDTH - LEFTBORDER, menutop + textheight('a') + 5); //去掉选中的菜单下方的小绿块 595 setfillcolor(TEXTCOLOR); 596 setfillcolor(MENUCOLOR); 597 solidrectangle(choose * menuwidth + left, menutop + textheight('a'), (choose + 1)*menuwidth + left, menutop + textheight('a') + 5); //画选中的菜单下方的小绿块 598 roundrect(5, menutop + textheight('a') + 5, WIDTH - 5, HEIGHT - 5, 5, 3); //画图片周围的绿色边框 599 solidrectangle(5, menutop + textheight('a') + 5, WIDTH - 5, menutop + textheight('a') + 10); //画图片上方与小绿块相连的绿色条 600 setfillcolor(TEXTCOLOR); 601 LOGFONT font1; 602 gettextstyle(&font1); 603 settextstyle(font1.lfHeight, 0, _T("宋体")); 604 string menu[11] = {" 打开", " 显示", " 查询路径", " 查询景点", " 修改景点", " 添加景点", " 删除景点", " 添加边", " 删除边"," 保存", " 退出"}; 605 for(int index = 0; index <= menunum - 1; index++) { 606 if(index == choose)settextcolor(SELECTCOLOR); 607 const char *p = menu[index].c_str(); 608 outtextxy(left + index * menuwidth, menutop, p); 609 if(index == choose)settextcolor(TEXTCOLOR); 610 } 611 settextstyle(&font1); 612 setlinecolor(MENUCOLOR); 613 for(int index1 = 0; index1 <= menunum + 1; index1++) { 614 line(left + index1 * menuwidth, menutop, left + index1 * menuwidth, menutop + textheight('a')); 615 } 616 LOGFONT font; 617 gettextstyle(&font); 618 settextstyle(10, 0, _T("宋体")); 619 settextcolor(TEXTCOLOR); 620 for(int lx = LEFTBORDER; lx <= WIDTH; lx += 50) { 621 outtextxy(lx, TOPBORDER - 10, &int_to_str(lx - LEFTBORDER)[0]); 622 } 623 for(int ly = TOPBORDER; ly <= HEIGHT - LEFTBORDER; ly += 50) { 624 outtextxy(10, ly - 5, &int_to_str(ly - TOPBORDER)[0]); 625 } 626 settextstyle(&font); 627 settextcolor(TEXTCOLOR); 628 FlushBatchDraw(); 629 setbkcolor(BKCOLOR); 630 settextcolor(TEXTCOLOR); 631 return choose; 632 } 633 int main() { 634 graph; 635 initgraph(WIDTH, HEIGHT); //,0);//SHOWCONSOLE|NOMINIMIZE 636 setbkcolor(BKCOLOR); 637 cleardevice(); 638 //int in = INT_MIN; 639 //FrontMenu(graph); 640 bool isfirstopen = true; 641 while(1) { 642 FrontMenu(graph); 643 //ShowAllVertex( graph); 644 if(isfirstopen) { 645 choose = 0; 646 } 647 else { 648 GetChoose( ); 649 } 650 FrontMenu(graph); 651 //ShowAllVertex( graph); 652 switch(choose) { 653 case 0: { 654 Open(graph, isfirstopen); 655 isfirstopen = false; 656 } 657 break; 658 case 1: { 659 ShowAllPath(graph); 660 ShowAllVertex( graph); 661 int vertexnum =graph.NumberOfVertices(),edgenum=graph.NumberOfEdges(); 662 string numofvertices; 663 numofvertices = "图中共有景点 " + int_to_str(vertexnum) + " 个\n"+"共有边 " + int_to_str(edgenum) + " 条\n"; 664 ::MessageBox(GetHWnd(), &numofvertices[0], "显示", MB_OK); 665 } 666 break; 667 case 2: { 668 ShowAllVertex( graph); 669 FindPath(graph); 670 ShowAllVertex( graph); 671 }; 672 break; 673 case 3: { 674 ShowAllVertex( graph); 675 FindVertex(graph); 676 }; 677 break; 678 case 4: { 679 ShowAllVertex( graph); 680 ModifyVertex(graph ); 681 }; 682 break; 683 case 5: { 684 ShowAllVertex( graph); 685 AddVertex(graph); 686 }; 687 break; 688 case 6: { 689 ShowAllVertex( graph); 690 DeleteVertex(graph); 691 }; 692 break; 693 case 7: { 694 ShowAllPath(graph); 695 ShowAllVertex( graph); 696 AddPath( graph); 697 } 698 break; 699 case 8: { 700 ShowAllPath(graph); 701 ShowAllVertex( graph); 702 DeletePath(graph); 703 } 704 break; 705 case 9: { 706 Save(graph); 707 } 708 break; 709 case 10: { 710 WinExec(_T("taskkill /f /im conhost.exe /t"), 1); 711 //WinExec(_T("taskkill /f /im 校园导游系统.exe /t"), 1); 712 exit(0); 713 } 714 break; 715 default: { 716 } 717 break; 718 } 719 } 720 return 0; 721 }
//Graph_List.h
1 //******************************** 类定义 ***************************************// 2 #ifndef _MYGraph_List_h_ 3 #define _MYGraph_List_h_ 4 #define LEFTBORDER 30 5 #define TOPBORDER 50 6 #include<string> 7 #include <fstream> 8 #include <graphics.h> 9 10 class Edge 11 { 12 private: 13 int VerAdj; 14 int cost; 15 Edge *link; 16 public: 17 Edge() 18 { 19 VerAdj = -1; 20 cost = -1; 21 link = NULL; 22 } 23 Edge(int VerAdji, int costi,Edge *linki): VerAdj(VerAdji), cost(costi),link(linki) //初始化 24 { 25 } 26 int &GetVerAdj() 27 { 28 return VerAdj; 29 } 30 int &Getcost() 31 { 32 return cost; 33 } 34 Edge *&Getlink() 35 { 36 return link; 37 } 38 }; 39 class Vertex 40 { 41 private: 42 string VerName; 43 string Describe; 44 Edge *adjacent; 45 int mark; 46 int x; 47 int y; 48 public: 49 Vertex() 50 { 51 VerName = "*"; 52 Describe = "*"; 53 adjacent = NULL; 54 mark=-1; 55 x=-1; 56 y=-1; 57 } 58 string &GetVerName() 59 { 60 return VerName; 61 } 62 string &GetDescribe () 63 { 64 return Describe; 65 } 66 Edge *&Getadj() 67 { 68 return adjacent; 69 } 70 int & GetMark() 71 { 72 return mark; 73 } 74 int & GetX() 75 { 76 return x; 77 } 78 int & GetY() 79 { 80 return y; 81 } 82 }; 83 class Graph_List 84 { 85 private: 86 Vertex *Head; 87 int graphsize; 88 int MaxCost; 89 IMAGE* map; 90 int InsertEdge_Do(const int &v1, const int &v2, int weight) //插入时尽量保证顺序排列 91 { 92 if(Head[v1].Getadj() == NULL) { 93 Head[v1].Getadj() = new Edge(v2, weight, NULL); //若邻接表为空 直接在adjacent后添加边 94 return 0; 95 } 96 Edge *p = Head[v1].Getadj(); 97 Edge *pt = p; 98 while((p != NULL)&&(p->GetVerAdj() < v2)) { 99 pt = p; 100 p = p->Getlink(); 101 } 102 if(p == NULL) { //到邻接表末端仍然比v2小 103 pt->Getlink() = new Edge(v2, weight, NULL); 104 return 0; 105 } 106 if(p == Head[v1].Getadj() && p->GetVerAdj() > v2) { //邻接表第一个就比v2大 107 Edge *q = new Edge(v2, weight, NULL); 108 q->Getlink() = p; 109 Head[v1].Getadj() = q; 110 return 0; 111 } 112 if(p->GetVerAdj() == v2) { 113 return -4; //插入边已存在 返回-4 114 } 115 if(p != Head[v1].Getadj() && p->GetVerAdj() > v2) { //正常在邻接表中间添加的情况 116 Edge *q = new Edge(v2, weight, NULL); 117 pt->Getlink() = q; 118 q->Getlink() = p; 119 return 0; 120 } 121 return 0; 122 } 123 int DeleteEdge_Do(const int &v1, const int &v2) 124 { 125 Edge *p = Head[v1].Getadj(); 126 if(p == NULL) 127 { 128 return -1; //返回-1表示所删除的边不存在 129 } 130 131 if(p->GetVerAdj() == v2) //邻接表第一个就是v2的情况 132 { 133 Head[v1].Getadj() = p->Getlink(); 134 delete p; 135 return 0; 136 } 137 Edge *pt = p; 138 while(p != NULL) 139 { 140 if(p->GetVerAdj() == v2) 141 { 142 pt->Getlink() = p->Getlink(); 143 delete p; 144 break; 145 } 146 pt = p; 147 p = p->Getlink(); 148 } 149 if(p == NULL) //到邻接表末端仍未找到v2 则边不存在 150 { 151 return -1; //返回-1表示所删除的边不存在 152 } 153 return 0; 154 } 155 int DeleteGraph_List() 156 { 157 for(int i = 0; i <= graphsize - 1; i++) 158 { 159 Edge *p = Head[i].Getadj(); 160 Edge *q = p; 161 while(p != NULL) 162 { 163 p = p->Getlink(); 164 delete q; 165 q = p; 166 } 167 } 168 delete [] Head; 169 delete map; 170 return 0; 171 } 172 public: 173 int& GetMaxCost() 174 { 175 return MaxCost; 176 } 177 Vertex*& GetHead() 178 { 179 return Head; 180 } 181 IMAGE *& GetMap() 182 { 183 return map; 184 } 185 int GetIndex(int marki) //按代号查找在顶点表中的位置 186 { 187 for(int i = 0; i <= graphsize - 1; i++) 188 { 189 if(marki == Head[i].GetMark()) 190 { 191 return i; 192 } 193 } 194 return -1; //找不到则返回-1 195 } 196 int GetIndex(string name) //按名称查找在顶点表中的位置 197 { 198 for(int i = 0; i <= graphsize - 1; i++) 199 { 200 if(name == Head[i].GetVerName()) 201 { 202 return i; 203 } 204 } 205 return -1; //找不到则返回-1 206 } 207 int graph_con(fstream &file,char* mapname) //插入边创建 208 { 209 DeleteGraph_List();//先把类里面之前的内容删除掉 210 map=new IMAGE; 211 loadimage(map, _T(mapname)); 212 file >> MaxCost; 213 file >> graphsize; 214 Head = new Vertex[graphsize]; 215 for(int i = 0; i <= graphsize - 1; i++) 216 { 217 file >> Head[i].GetVerName(); 218 file >> Head[i].GetDescribe(); 219 file >> Head[i].GetMark(); 220 file >> Head[i].GetX(); 221 Head[i].GetX()+=LEFTBORDER; //加左边界 222 file >> Head[i].GetY(); 223 Head[i].GetY()+=TOPBORDER; //加上边界 224 Head[i].Getadj() = NULL; 225 } 226 int edgenum; 227 file >> edgenum; 228 for(int j = 0; j <= edgenum - 1; j++) 229 { 230 int v1, v2, weight; 231 file >> v1; 232 file >> v2; 233 double dx=Head[GetIndex(v2)].GetX(); 234 double sx=Head[GetIndex(v1)].GetX(); 235 double dy=Head[GetIndex(v2)].GetY(); 236 double sy=Head[GetIndex(v1)].GetY(); 237 weight=(double)sqrt(((dx-sx)*(dx-sx)+(dy-sy)*(dy-sy))/24250.0)*300.0; //通过坐标计算边长度 赋给weight 238 InsertEdge(GetIndex(v1),GetIndex(v2), weight); 239 } 240 return 0; 241 } 242 Graph_List() //构造函数 构造一个空图 243 { 244 Head=NULL; 245 map=NULL; 246 map=new IMAGE; 247 graphsize=0; 248 MaxCost=0; 249 } 250 ~Graph_List(){ 251 DeleteGraph_List(); 252 } 253 int SaveFile(char* filename){ 254 system("del filename "); //删除文件 255 ofstream fl(filename);//打开文件用于写,若文件不存在就创建它 256 if(!fl)return -1;//打开文件失败则结束运行 257 fl << GetMaxCost() << endl; 258 fl << NumberOfVertices() << endl; 259 for(int i = 0; i <= NumberOfVertices() - 1; i++) { 260 fl << Head[i].GetVerName() << "\t\t\t" << Head[i].GetDescribe() << "\t\t\t\t\t\t" << Head[i].GetMark() << "\t" << Head[i].GetX() - LEFTBORDER << "\t" << Head[i].GetY() - TOPBORDER << endl; 261 } //用制表符对齐 262 fl << endl; 263 int numofedges =NumberOfEdges() * 2; 264 fl << numofedges << endl; 265 int num = 0; 266 for(int j = 0; j <= NumberOfVertices() - 1; j++) { 267 Edge *p = Head[j].Getadj(); 268 while(p != NULL) { 269 if(num == 5) { 270 fl << endl; 271 num = 0; 272 } 273 fl << GetHead()[j].GetMark() << "\t" << GetHead()[p->GetVerAdj()].GetMark() << endl; 274 p = p->Getlink(); 275 num++; 276 } 277 } 278 fl.close(); 279 return 0; 280 } 281 bool GraphEmpty()const 282 { 283 return graphsize == 0; 284 } 285 int NumberOfVertices ()const 286 { 287 return graphsize; 288 } 289 int NumberOfEdges ()const 290 { 291 int n = 0; 292 for(int i = 0; i <= graphsize - 1; i++) 293 { 294 Edge *p = Head[i].Getadj(); 295 while(p != NULL) 296 { 297 n++; 298 p = p->Getlink(); 299 } 300 } 301 return n / 2; //返回边的数目 不计重复边 302 } 303 int GetWeight(const int &v1, const int &v2) 304 { 305 if(v1 > graphsize - 1 || v2 > graphsize - 1 || v1 < 0 || v2 < 0) 306 { 307 //cout << "查找元素超界!" << endl; 308 return -1; 309 } 310 if(v1 == v2) /// 311 { 312 return 0; 313 } 314 Edge *p = Head[v1].Getadj(); 315 while(p != NULL && p->GetVerAdj() != v2) 316 { 317 p = p->Getlink(); 318 } 319 if(p != NULL) 320 { 321 return p->Getcost(); 322 } 323 else 324 return MaxCost + 1; //两点之间没有边则返回 MaxCost + 1 325 } 326 void InsertVertex(string name,string describe,int mark,int x,int y) 327 { 328 Vertex *head = new Vertex[graphsize + 1]; //创建一个新的顶点表 大小为现有大小再加1 329 for(int i = 0; i <= graphsize - 1; i++) //复制现有顶点表的内容到新顶点表 330 { 331 head[i] = Head[i]; 332 } 333 head[graphsize].GetVerName() = name; //把新添加的顶点加在新顶点表最后一个位置 334 head[graphsize].GetDescribe() = describe; 335 head[graphsize].GetMark() = mark; 336 head[graphsize].GetX() = x; 337 head[graphsize].GetY() = y; 338 head[graphsize].Getadj() = NULL; 339 delete [] Head; //删除原顶点表 340 Head = head; //把Head指针指向新顶点表 341 graphsize++; //更新顶点数目 342 } 343 int InsertEdge(int v1,int v2, int weight) 344 { 345 if(v1 > graphsize - 1 || v2 > graphsize - 1 || v1 < 0 || v2 < 0) 346 { 347 //cerr << "插入元素超界!无法完成操作!" << endl; 348 return -1; //插入元素超界返回-1 349 } 350 if(weight > MaxCost) 351 { 352 //cerr << "插入权值超出最大权值!无法完成操作!" << endl; 353 return -2; //返回-2表示权值过大 354 } 355 356 if(v1 == v2) 357 { 358 //cerr << "操作不合法" << endl; 359 return -3; 360 } 361 int i=InsertEdge_Do(v1, v2, weight); 362 if(i==-4){ //边已存在 363 return i; 364 } 365 InsertEdge_Do(v2, v1, weight); 366 return i; 367 } 368 int DeleteVertex(const int &v) 369 { 370 if(v > graphsize - 1 || v < 0) 371 { 372 //cerr << "删除元素超界!" << endl; 373 return -1; //超界返回-1 374 } 375 for(int i = 0; i <= graphsize - 1; i++) 376 { 377 DeleteEdge(i, v); //删除指向该顶点的所有边 378 } 379 for(int j = v; j <= graphsize - 2; j++) 380 { 381 Head[j] = Head[j + 1]; //把该顶点后边的元素向前挪一个位置 382 } 383 graphsize--; //更新graphsize 384 for(int k = 0; k <= graphsize - 1; k++) 385 { 386 Edge *p = Head[k].Getadj(); 387 while(p != NULL) 388 { 389 if(p->GetVerAdj() > v) 390 { 391 p->GetVerAdj()--; //所有边之中指向所删除顶点之后位置的 都要减1 392 } 393 p = p->Getlink(); 394 } 395 } 396 return 0; 397 } 398 int ModifyVertex(int v,string& name,string& describe,int& marki,int& x,int& y){ 399 if(v < 0 || v > NumberOfVertices() - 1) { 400 return -1; 401 } 402 Head[v].GetVerName() = name; 403 Head[v].GetDescribe() = describe; 404 Head[v].GetMark() = marki; 405 Head[v].GetX() = x; 406 Head[v].GetX() += LEFTBORDER; 407 Head[v].GetY() = y; 408 Head[v].GetY() += TOPBORDER; 409 return 0; 410 } 411 int DeleteEdge(int v2, int v1) 412 { 413 if(v1 > graphsize - 1 || v2 > graphsize - 1 || v1 < 0 || v2 < 0) 414 { 415 //cerr << "删除元素超界!" << endl; 416 return -1; 417 } 418 if(v1 == v2) 419 { 420 return -1; 421 } 422 int i=DeleteEdge_Do(v1,v2); 423 if(i==-1){return i;} 424 DeleteEdge_Do(v2,v1); 425 return i; 426 } 427 int DShortestPath(const int v,int*& path) 428 { 429 int n = graphsize; 430 int *s = new int[n]; 431 int *dist = new int[n]; 432 int i = 0, temp = 0; 433 for (i = 0; i < n; i++) 434 { 435 s[i] = 0; 436 dist[i] = MaxCost*graphsize*(graphsize-1)/2; 437 path[i] = -1; 438 } 439 int u = v; 440 Edge *p = NULL; 441 dist[u] = 0; 442 s[u] = 1; 443 path[u] = u; 444 for (i = 0; i < n; i++) 445 { 446 s[u] = 1; 447 p = Head[u].Getadj(); 448 while (p != NULL) 449 { 450 temp = p->GetVerAdj(); 451 if (dist[u] + p->Getcost ()< dist[temp]) 452 { 453 dist[temp] = dist[u] + p->Getcost(); 454 path[temp] = u; 455 } 456 p = p->Getlink(); 457 } 458 temp =MaxCost*graphsize*(graphsize-1)/2;; 459 for (int j = 0; j < n; j++) 460 { 461 if (s[j] == 0 && dist[j] < temp) 462 { 463 temp = dist[j]; 464 u = j;//未访问中最小 465 } 466 } 467 } 468 delete[]s; 469 delete[]dist; 470 return 0; 471 } 472 }; 473 #endif
//Stack.h
1 #ifndef _MYStack_h_ 2 #define _MYStack_h_ 3 template<class TL> 4 class LStack; 5 //结点定义 6 template<class TL> 7 class LStackNode 8 { 9 private: 10 TL data; 11 LStackNode<TL>* next; 12 public: 13 friend class LStack<TL>; 14 LStackNode() 15 { 16 next=NULL; 17 } 18 LStackNode(TL item,LStackNode<TL>* nextnode=NULL) 19 { 20 data=item; 21 next=nextnode; 22 } 23 LStackNode(LStackNode<TL>& node) 24 { 25 data=node.data; // 为什么必须是引用&才行 26 next=node.next; 27 } 28 }; 29 //栈定义 30 template<class TL> 31 class LStack 32 { 33 private: 34 LStackNode<TL> * top; 35 public: 36 LStack() 37 { 38 top=NULL; 39 } 40 bool Push(const TL& item) 41 { 42 LStackNode<TL>* p=top; 43 top=new LStackNode<TL>; 44 top->data=item; 45 top->next=p; 46 return true; 47 } 48 bool Pop( TL& item) 49 { 50 if(top==NULL) 51 { 52 return false; 53 } 54 else 55 { 56 item=top->data; 57 LStackNode<TL> * p=top; 58 top=top->next; 59 delete p; 60 } 61 return true; 62 } 63 bool Peek( TL& item) 64 { 65 if(top==NULL) 66 { 67 return false; 68 } 69 else 70 { 71 item=top->data; 72 } 73 } 74 ~LStack() 75 { 76 LStackNode<TL>* p=top; 77 while(top!=NULL) 78 { 79 top=top->next; 80 delete p; 81 p=top; 82 } 83 top=p=NULL; 84 } 85 bool IsEmpty() 86 { 87 return top==NULL; 88 } 89 }; 90 #endif 91
//functions.h
1 #ifndef _Functions_h_ 2 #define _Functions_h_ 3 #include<iostream> 4 #include<string> 5 #include<math.h> 6 #include <sstream> 7 using namespace std; 8 string int_to_str(int n){ 9 std::stringstream ss; 10 std::string str; 11 ss<<n; 12 ss>>str; 13 return str; 14 } 15 int str_to_num1(const char*& str) 16 { 17 if(!(str[0]=='-'||(str[0]>='0'&&str[0]<='9'))){ 18 return INT_MIN; 19 } 20 int n=0; 21 while(str[n]!='\0'){ 22 n++; 23 } 24 int number=0; 25 if(str[0]!='-'){ 26 for(int i=0;i<n;i++){ 27 if(!(str[i]>='0'&&str[i]<='9')){ 28 return INT_MIN; 29 } 30 number+=(str[i]-'0')*pow(10,n-i-1); 31 } 32 } 33 if(str[0]=='-'){ 34 for(int i=1;i<n;i++){ 35 if(!(str[i]>='0'&&str[i]<='9')){ 36 return INT_MIN; 37 } 38 number+=(str[i]-'0')*pow(10,n-i-1); 39 } 40 number*=-1; 41 } 42 return number; 43 } 44 int str_to_num(const string& str) 45 { 46 const char* data=str.c_str(); 47 int number=str_to_num1(data); 48 return number; 49 } 50 #endif
资源文件:
map.txt内容
10000 94 东门 学校正门 1 974 182 图书馆 一楼可自习,可通宵 2 693 210 计算机楼 计算机学院和软件学院公用实验教学楼 3 665 335 第三教学楼 一教二教不在本校区╮(╯_╰)╭ 4 739 277 逸夫楼 公共教学楼 5 585 147 北门 最繁忙的学校大门 6 528 25 办公楼 行政人员办公楼 7 528 219 四食堂 最小食堂,却居于最重要位置 8 420 252 体育馆 大型活动举办地 9 440 300 体育运动场 主体育场 10 325 277 南苑 学生公寓 11 380 460 小北门 小校门 12 365 129 经信教学楼 经济信息学院教学楼 13 149 448 北苑 学生公寓 14 215 169 新食堂 食堂,有两层 15 252 383 李四光楼 地质教学楼 16 34 343 * * 17 202 427 * * 18 213 245 * * 19 261 237 * * 20 249 194 * * 21 475 235 * * 22 346 200 * * 23 388 183 * * 24 399 321 * * 25 299 362 * * 26 447 157 * * 27 497 276 * * 28 529 352 * * 29 649 297 * * 30 759 210 * * 31 651 211 * * 32 545 256 * * 33 978 10 * * 34 439 140 音乐厅 音乐厅 35 489 125 逸夫图书馆 校史陈列馆 36 496 147 麦克德尔米德实验室 实验室 37 568 115 * * 38 21 303 * * 39 760 182 唐敖庆楼 唐敖庆楼 40 757 125 * * 41 758 151 * * 42 650 154 * * 43 597 175 * * 44 521 205 外语楼 外语学院教学楼 45 550 115 篮球场 新食堂篮球场 46 231 340 匡亚明楼 匡亚明楼 47 614 375 * * 48 596 321 南门 南门 49 479 521 * * 50 517 324 莘子园食堂 莘子园食堂 51 365 369 * * 52 354 340 * * 53 572 459 * * 54 432 397 * * 55 446 430 * * 56 453 451 * * 57 551 410 * * 58 637 420 * * 59 688 389 * * 60 274 276 * * 61 239 299 * * 62 114 303 * * 63 136 338 * * 64 72 383 * * 65 170 363 * * 66 202 404 * * 67 648 176 * * 68 464 205 * * 69 315 422 * * 70 373 395 * * 71 419 375 * * 72 330 478 * * 73 272 488 * * 74 260 441 * * 75 201 507 * * 76 201 459 经信公寓 经信公寓 77 277 525 * * 78 658 317 * * 79 132 453 西门 西门 80 66 488 物理楼 物理楼 81 644 83 生科楼 生命科学楼 82 859 81 * * 83 861 180 * * 84 862 259 东荣 0 85 804 211 数学楼 数学学院数学楼 86 913 259 * * 87 711 85 * * 88 718 56 * * 89 789 57 * * 90 796 80 * * 91 861 207 * * 92 861 150 * * 93 410 226 * * 94 511 184 284 1 33 1 83 2 30 2 31 3 59 3 78 4 29 4 30 4 78 4 85 5 37 5 43 6 12 6 33 6 35 6 37 6 81 7 21 7 32 7 44 8 9 8 21 8 93 9 8 9 24 9 27 9 50 10 19 10 22 10 24 10 25 11 55 11 72 12 6 12 20 12 23 12 34 13 17 13 79 14 20 14 38 15 25 15 66 16 20 16 38 16 62 16 64 17 13 17 66 17 76 18 19 18 62 19 10 19 18 19 20 19 22 19 60 20 12 20 14 20 16 20 19 21 7 21 8 21 26 21 27 22 10 22 19 22 23 22 24 23 12 23 22 23 26 23 93 24 9 24 10 24 22 24 52 24 71 25 10 25 15 25 52 25 60 25 69 26 21 26 23 26 34 27 9 27 21 27 32 27 50 28 48 28 50 28 53 28 54 29 4 29 31 29 32 29 48 29 78 30 2 30 4 30 39 30 85 31 2 31 29 31 32 31 43 31 67 32 7 32 27 32 29 32 31 33 1 33 6 34 12 34 26 34 35 35 6 35 34 35 36 36 35 36 45 36 94 37 5 37 6 37 45 37 81 38 14 38 16 39 30 39 40 39 41 39 67 39 83 40 39 41 39 41 42 41 92 42 41 42 43 42 67 42 81 43 5 43 31 43 42 43 44 43 67 44 7 44 43 44 94 45 36 45 37 46 61 46 66 47 48 47 58 48 28 48 29 48 47 49 53 49 56 50 9 50 27 50 28 51 52 51 70 52 24 52 25 52 51 53 28 53 49 53 58 54 28 54 55 54 71 55 11 55 54 55 56 56 49 56 55 56 57 57 56 58 47 58 53 58 59 59 3 59 58 60 19 60 25 60 61 61 46 61 60 61 65 62 16 62 18 62 63 63 62 63 64 63 65 64 16 64 63 64 79 65 61 65 63 65 66 66 15 66 17 66 46 66 65 67 31 67 39 67 42 67 43 68 93 68 94 69 25 69 70 69 72 69 74 70 51 70 69 70 71 71 24 71 54 71 70 72 11 72 69 72 73 73 72 73 74 73 75 73 77 74 69 74 73 74 76 75 73 75 76 76 17 76 74 76 75 77 73 78 3 78 4 78 29 79 13 79 64 79 80 80 79 81 6 81 37 81 42 81 87 82 90 82 92 83 1 83 39 83 91 83 92 84 86 84 91 85 4 85 30 85 91 86 84 87 81 87 88 88 87 88 89 89 88 89 90 90 82 90 89 91 83 91 84 91 85 92 41 92 82 92 83 93 8 93 23 93 68 94 36 94 44 94 68
map.jpg
大二上学期数据结构课程设计写此程序。
2016.4.12更新博客。