校园导游咨询系统(Dijkstra算法,图形化界面)
校园导游咨询系统
- 前言
- 课设要求
- 准备工作
- 编程
- 演示
前言
最近布置了数据结构的作业,终于把代码敲出来了,总而言之还是挺满意的,受到了一些文章的启发,所以想把这些记录下来所以特别感谢[图形化界面](https://blog.csdn.net/weixin_44044411/article/details/104276757?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160719106219726891124613%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=160719106219726891124613&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-2-104276757.first_rank_v2_pc_rank_v29&utm_term=C%E8%AF%AD%E8%A8%80%E5%B0%86%E8%BE%93%E5%85%A5%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%BE%9D%E6%AC%A1%E6%89%AB%E6%8F%8F%E5%88%B0%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%E9%87%8C%E9%9D%A2&spm=1018.2118.3001.4449)这篇文章
课设要求
(1) 采用Dijkstra算法提供任意两个场所间的最短路径,(这里因为距离并未结合实际,所以我就没输出了)并能输出最短路径长度及路径(以场所名称表示);
(2) 以图中顶点表示校内各场所,存放场所名称、代号、简介等信息;以边表示路径,存放路径长度等相关信息;
(3) 结点数可改变(可增加或删除场所);
(4) 初始图至少包括10各场所;
(5) 设计简单菜单能进行操作选择。
准备工作
easyx的下载链接如下:(本文使用的版本是2020最新版)
https://www.easyx.cn/downloads/
注:使用easyx需要注意它兼容的编译器(下载的帮助文件会写),不同的easyx兼容的编译器不同,但总是和visual C++6兼容(和字符编码有关),本文以visual C++6编译器为例书写代码。
我下载的时候有界面帮你直接安装了
编程
感觉最好的办法还是结合实际代码,所以直接上代码,几乎每一段我都上了注释。当然因为是初学,所以很多代码可能会有冗余,会有更好的写法,勿喷
效果图:
舍友帮我画的背景图
上代码,推荐还是用cpp保存
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<graphics.h>
#include<conio.h>
#include<Windows.h>
#define max 10000
#define _CRT_SECURE_NO_WARNINGS 1 //解决sscanf不安全
using namespace std;IMAGE BJ;//背景图片
int r2[3][4] = { {900,30,990,70},{900,120,990,160} ,{900,210,990,310} };//增加地点,减少地点,鼠标坐标显示的 矩阵位置
int r[50][2];//地图上所有地点坐标的矩阵typedef struct ArcCell
{int adj; //权值 两点之间的距离int* info; //两点之间其他信息,本代码没用
}ArcCell;//途中两个地点之间的信息
typedef struct vexs
{char name[40];//地点的名字int x, y;//顶点坐标
};//地点信息
typedef struct MGraph
{vexs vexs[20]; //顶点矩阵ArcCell arcs[20][20]; //边int vexnum, arcnum; //图的当前顶点数和弧数
}MGraph;//地图的基本信息int button_judge(int x, int y,MGraph G)
{for (int i = 0; i < G.vexnum; i++) {if (x > r[i][0] - 40 && x < r[i][0] + 40 && y > r[i][1] - 40 && y < r[i][1] + 40)return i+1;}return 0;
}//判断鼠标是否在地图中地点的位置
int button_judge1(int x, int y)
{if (x > r2[0][0] && x < r2[0][2] && y > r2[0][1] && y < r2[0][3])return 1;if (x > r2[1][0] && x < r2[1][2] && y > r2[1][1] && y < r2[1][3])return 2;return 0;
} //判断鼠标是否在增加或者删除地点的窗口处
int LocateVex(MGraph G, char v[40]) {for (int i = 0; i < G.vexnum; i++) {if (strcmp(G.vexs[i].name,v)==0) {return i;break;}}
} //判断地图上的地点在图(指数据结构中的图)中的位置void CreateUDN(MGraph& G) {G.vexnum = 10;G.arcnum = 17;//图中的地点,几个地点之间相通的路的个数strcpy_s(G.vexs[0].name, "沁园");G.vexs[0].x = 100; G.vexs[0].y = 700;strcpy_s(G.vexs[1].name, "食堂");G.vexs[1].x = 250; G.vexs[1].y = 600;strcpy_s(G.vexs[2].name, "文德楼");G.vexs[2].x = 800; G.vexs[2].y = 650;strcpy_s(G.vexs[3].name, "逸夫楼");G.vexs[3].x = 50; G.vexs[3].y = 400;strcpy_s(G.vexs[4].name, "操场");G.vexs[4].x = 300; G.vexs[4].y = 500;strcpy_s(G.vexs[5].name, "计软楼");G.vexs[5].x = 250; G.vexs[5].y = 70;strcpy_s(G.vexs[6].name, "长望楼");G.vexs[6].x = 250; G.vexs[6].y = 250;strcpy_s(G.vexs[7].name, "北辰楼");G.vexs[7].x = 650; G.vexs[7].y = 50;strcpy_s(G.vexs[8].name, "藕舫楼");G.vexs[8].x = 700; G.vexs[8].y = 150;strcpy_s(G.vexs[9].name, "明德楼");G.vexs[9].x = 670; G.vexs[9].y = 250;//我设置的固定地点for (int i = 0; i < G.vexnum; i++) {for (int j = 0; j < G.vexnum; j++) {G.arcs[i][j].adj = max;G.arcs[i][j].info = NULL;}}//赋初值为max 这样固定都不能走,再设置能走的for (int k = 0; k < G.arcnum; k++) //设置能走的几个点{char v1[40], v2[40];if (k == 0) {strcpy_s(v1, "沁园");strcpy_s(v2, "逸夫楼");}if (k == 1) {strcpy_s(v1, "沁园");strcpy_s(v2, "食堂");}if (k == 2) {strcpy_s(v1, "食堂");strcpy_s(v2, "文德楼");}if (k == 3) {strcpy_s(v1, "沁园");strcpy_s(v2, "操场");}if (k == 4) {strcpy_s(v1, "食堂");strcpy_s(v2, "操场");}if (k == 5) {strcpy_s(v1, "逸夫楼");strcpy_s(v2, "操场");}if (k == 6) {strcpy_s(v1, "计软楼");strcpy_s(v2, "逸夫楼");}if (k == 7) {strcpy_s(v1, "长望楼");strcpy_s(v2, "逸夫楼");}if (k == 8) {strcpy_s(v1, "计软楼");strcpy_s(v2, "长望楼");}if (k == 9) {strcpy_s(v1, "计软楼");strcpy_s(v2, "北辰楼");}if (k == 10) {strcpy_s(v1, "长望楼");strcpy_s(v2, "明德楼");}if (k ==11) {strcpy_s(v1, "长望楼");strcpy_s(v2, "操场");}if (k == 12) {strcpy_s(v1, "操场");strcpy_s(v2, "文德楼");}if (k == 13) {strcpy_s(v1, "北辰楼");strcpy_s(v2, "藕舫楼");}if (k == 14) {strcpy_s(v1, "藕舫楼");strcpy_s(v2, "明德楼");}if (k == 15) {strcpy_s(v1, "操场");strcpy_s(v2, "明德楼");}if (k == 16) {strcpy_s(v1, "明德楼");strcpy_s(v2, "文德楼");}int i = LocateVex(G, v1);int j = LocateVex(G, v2);//找到v1 v2在图中位置int w = sqrt(pow((G.vexs[i].x - G.vexs[j].x), 2) + pow((G.vexs[i].y - G.vexs[j].y), 2));G.arcs[i][j].adj = w; //取弧无相关信息,给两个点之间赋值距离G.arcs[j][i] = G.arcs[i][j];setlinecolor(BLACK);setlinestyle(PS_SOLID);//设置画线的点是黑色 实现line(G.vexs[i].x, G.vexs[i].y, G.vexs[j].x, G.vexs[j].y);//连线}
}
void DIJ(MGraph G,int v0,int (&p)[100][100])
{int final[100],D[100];for (int v = 0; v < G.vexnum; ++v){final[v] = 0;//当final[v]为1的话,即已求得起始点到该点最短路径,此时默认都没取得D[v] = G.arcs[v0][v].adj;//D[v]是从起点到该点的距离for (int w = 0; w < G.vexnum; w++)p[v][w] = 0;//初始化 p[v][w]是从起点v0到v点中 的w点是不是能走的点 为0不是 为1是if (D[v] < max){p[v][v0] = 1;p[v][v] = 1;}//从起始点到这个点能走的话 就给他赋值1,当然自己肯定是要走的}D[v0] = 0; //从起点到起点距离必然为0final[v0] = 1;//每次求得v0到某个v顶点的最短路径,并将v加到s集for (int i = 1; i < G.vexnum; i++){int min = max,w=0,v=0;for (w = 0; w < G.vexnum; w++){if (!final[w])//没求到最短路径(下一个最短路径的点){if (D[w] < min){v = w;min = D[w];}}}//此时v点是附近一个最近的点final[v] = 1; //距v0最近的v加入S集for (w = 0; w < G.vexnum; w++){if (!final[w] && ((min + G.arcs[v][w].adj) < D[w]))//如果该点不是从起点到它最短路径的点并且从起点到离起点最近的点再到该点的距离小于从起点直接到他的距离{D[w] = min + G.arcs[v][w].adj;//那么到该点就走v点for (int j = 0; j < G.vexnum; j++) {p[w][j] = p[v][j];//从起点到该点最短路径上的点跟从起点到v点最短路径上的点一样,也就是把到w加到最短路径上}p[w][w]=1;}}}
}int main() {short win_width, win_height;//宽度高度win_width = 1000;win_height = 1000;initgraph(win_width, win_height);//打开地图for (int i = 0; i < 256; i += 5){setbkcolor(RGB(i, i, i));//设置背景色,原来默认黑色cleardevice();//清屏(取决于背景色)Sleep(30);//延时30ms,可以不要的}//这里是为了把背景板变白色好看点,如果你设置了背景地图就不用加这一步了loadimage(&BJ, "C:\\Users\\roar\\Desktop\\数据结构地图\\BJ.jpg", 1000, 1000);//下载背景地图,这里我把地图地址放在自己的电脑里,用的绝对地址,画布大小为1000*1000,舍友帮我画的putimage(0, 0, &BJ);//在(0,0)的位置打开地图LOGFONT f;//字体样式指针gettextstyle(&f);//获取字体样式strcpy_s(f.lfFaceName, _T("楷体"));//我用了楷体,也可以宋体balabalaf.lfQuality = ANTIALIASED_QUALITY;//抗锯齿settextstyle(&f);//给字体设定settextcolor(BLUE);//设置文本颜色setlinecolor(BLACK);setlinestyle(PS_SOLID);MOUSEMSG m;//鼠标指针char a[40], b[40];//这里是复制起始点和终点名字的字符串(现在看看好像不要也可以?)MGraph G;//定义图CreateUDN(G);//设置图int p[100][100];//存放最短路径的数组,详见DIJ里那个pfor (int i = 0; i < G.vexnum; i++){r[i][0] = G.vexs[i].x;r[i][1] = G.vexs[i].y;}//把几个地点放到矩阵里,这样好在图形化见面设置几个点的方框for (int i = 0; i < G.vexnum; i++){RECT R = { r[i][0] - 40,r[i][1] - 40,r[i][0] + 40,r[i][1] + 40 };drawtext(G.vexs[i].name, &R, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//把地点的名字输到图上}RECT R1 = { r2[0][0],r2[0][1],r2[0][2],r2[0][3] };RECT R2 = { r2[1][0],r2[1][1],r2[1][2],r2[1][3] };RECT R3 = { r2[2][0],r2[2][1],r2[2][2],r2[2][3] };//pRECT指针是矩形指针,定义这个几个框drawtext("增加地点", &R1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);drawtext("删除地点", &R2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//输入文本rectangle(r2[0][0], r2[0][1], r2[0][2], r2[0][3]);rectangle(r2[1][0], r2[1][1], r2[1][2], r2[1][3]);rectangle(r2[2][0], r2[2][1], r2[2][2], r2[2][3]);//画上框框int event = 0,event2=0,clickflag=0,t=0,t2=0,t3=0,jilu1=0,jilu2=0;//event是移动鼠标时看在哪个地点框里,event2看移动到增加按钮还是删除按钮,clickflag看是起点还是终点,t t2 t3是点击时候的,jilu1、jilu2是我删除连线用的while (true){m = GetMouseMsg();switch (m.uMsg){case WM_MOUSEMOVE: {setrop2(R2_XORPEN);//二元光栅,会因背景色变化setlinecolor(LIGHTCYAN);//亮青色setlinestyle(PS_SOLID, 3);//画线:实线,10磅setfillcolor(WHITE);//填充色char text_t[12];sprintf(text_t, "[%d,%d]", m.x, m.y);drawtext(text_t, &R3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//打印鼠标的实时坐标if (button_judge(m.x, m.y, G) != 0)//首先在框里{if (event != button_judge(m.x, m.y, G))//不重复闪动{event = button_judge(m.x, m.y, G);//确定位置fillrectangle(r[event - 1][0] - 40, r[event - 1][1] - 40, r[event - 1][0] + 40, r[event - 1][1] + 40);//填充颜色}}else if (event != 0)//从框里移出来{if (event != 0) {fillrectangle(r[event - 1][0] - 40, r[event - 1][1] - 40, r[event - 1][0] + 40, r[event - 1][1] + 40);//把那里的颜色复原event = 0;}}else if (button_judge1(m.x, m.y) != 0){if (event2 != button_judge1(m.x, m.y)){event2 = button_judge1(m.x, m.y);fillrectangle(r2[event2 - 1][0], r2[event2 - 1][1], r2[event2 - 1][2], r2[event2 - 1][3]);//如果在增加删除的框里,框框变色}}else if (event2 != 0){if (event2 != 0){fillrectangle(r2[event2 - 1][0], r2[event2 - 1][1], r2[event2 - 1][2], r2[event2 - 1][3]);//框框恢复颜色event2 = 0;}}break;}case WM_LBUTTONDOWN://摁下鼠标setrop2(R2_NOTXORPEN);//二元光栅for (int i = 0; i <= 10; i++){setlinecolor(RGB(25 * i, 25 * i, 25 * i));//颜色circle(m.x, m.y, 2 * i);//画圈圈Sleep(10);circle(m.x, m.y, 2 * i);//删掉圈圈}if (button_judge1(m.x, m.y) != 0)//点到增加或者删除的框框{t2 = button_judge1(m.x, m.y);//t2记录点的是增加还是删除if (t2 == 1)//增加的框框{G.vexnum++;//图中的地点数目增加int num;char s[140];InputBox(s, 140, "请输入增加地点的名称、坐标(0~1000),(0~1000)、与几个地点有路");sscanf(s, "%s%d%d%d", &G.vexs[G.vexnum-1].name, &G.vexs[G.vexnum-1].x, &G.vexs[G.vexnum - 1].y, &num);//注意,这里的sscanf在vs里面是不安全的用法,所以要在属性的预处理器里加入_CRT_SECURE_NO_WARNINGS;r[G.vexnum - 1][0] = G.vexs[G.vexnum - 1].x;r[G.vexnum - 1][1] = G.vexs[G.vexnum - 1].y;//在地图中矩阵里增加新的框框位置setlinecolor(BLACK);setlinestyle(PS_DOT);//黑线 点阵RECT R = { r[G.vexnum - 1][0] - 40,r[G.vexnum - 1][1] - 40,r[G.vexnum - 1][0] + 40,r[G.vexnum - 1][1] + 40 };drawtext(G.vexs[G.vexnum - 1].name, &R, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//给新的地点设置框框,写上名字for (int i=G.vexnum-1,j = 0; j < G.vexnum; j++){G.arcs[i][j].adj = max;G.arcs[i][j].info = NULL;G.arcs[j][i].adj = max;G.arcs[j][i].info = NULL;}//给新地点附上信息,初始化G.arcnum += num;//新的路也多了char c[40];while (num--) //每条路都要输入是连接哪个点的{InputBox(c, 40, "请输入哪几个地点(一次一个)");sscanf(c, "%s", &c);//不安全噢for (int t = 0; t < G.vexnum; t++){if (strcmp(c, G.vexs[t].name) == 0){int i = LocateVex(G, c);int j = LocateVex(G, G.vexs[G.vexnum-1].name);//找到两个地点在图中的位置int w = sqrt(pow((G.vexs[i].x - G.vexs[j].x), 2) + pow((G.vexs[i].y - G.vexs[j].y), 2));//计算距离G.arcs[i][j].adj = w; //取弧无相关信息,存入距离信息G.arcs[j][i] = G.arcs[i][j];//矩阵上下要是一样的,双向路setlinecolor(BLACK);setlinestyle(PS_SOLID);//实线 黑色line(G.vexs[i].x, G.vexs[i].y, G.vexs[j].x, G.vexs[j].y);//给新路连线}}}}if (t2 == 2) {//这里是删除地点char s[140];InputBox(s, 140, "请输入删除地点的名称");sscanf(s, "%s", &s);for (int i = 0; i < G.vexnum; i++) {if (strcmp(s, G.vexs[i].name) == 0)//看看是哪个地点被删了{setrop2(R2_COPYPEN);setlinecolor(WHITE);setlinestyle(PS_SOLID,5);//这里用了白色的覆盖笔,准备把这里硬核全部涂白setfillcolor(WHITE);RECT R = { r[i][0] - 40,r[i][1] - 40,r[i][0] + 40,r[i][1] + 40 };rectangle(r[i][0] - 40, r[i][1] - 40, r[i][0] + 40, r[i][1] + 40);fillrectangle(r[i][0] - 40, r[i][1] - 40, r[i][0] + 40, r[i][1] + 40);//在这个位置从新弄个框框,硬核涂白消失法for (int j = 0; j < G.vexnum; j++){if (G.arcs[i][j].adj != max)//找到有连接的路{setrop2(R2_COPYPEN);setlinecolor(WHITE);setlinestyle(PS_SOLID, 5);line(G.vexs[i].x, G.vexs[i].y, G.vexs[j].x, G.vexs[j].y);//把相连的路全部涂白了G.arcs[i][j].adj = max;G.arcs[j][i] = G.arcs[i][j];//把路之间距离设为最大,理论上消失它RECT R2{ r[j][0] - 40, r[j][1] - 40, r[j][0] + 40, r[j][1] + 40 };drawtext(G.vexs[j].name,&R2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//因为连线是从地点的中点开始连的,所以会把地点的名字给盖掉一些些,所以我们重新打印地点的名字}}}}}}setrop2(R2_XORPEN);//二元光栅,会因背景色变化setlinecolor(LIGHTCYAN);//亮青色setlinestyle(PS_SOLID, 3);//画线:实线,10磅setfillcolor(WHITE);//填充色if (button_judge(m.x, m.y, G) != 0)//这里是鼠标如果点到地图上的地点的话{if (t != button_judge(m.x, m.y, G) && clickflag == 0)//这里的clickflag是为了判断是第一次点还是第二次点,这里是第一次点,所以是起点,t!=button_judge是为了防止重复点{t = button_judge(m.x, m.y, G);//算出是哪个地点if (t-1 == 0){MessageBox(NULL, "沁园:你住的地方", "起始点", MB_OK);//弹出窗口MessageBox,其实可以用drawtext找个地方单独打印,我这时候已经犯懒了,NULL是对弹出的窗口不做设置,MB_OK是确认按钮}if (t-1 == 1){MessageBox(NULL, "食堂:中老食堂,都吃过的吧", "起始点", MB_OK);}if (t-1 == 2){MessageBox(NULL, "文德楼:拿快递拿快递!", "起始点", MB_OK);}if (t-1 == 3){MessageBox(NULL, "逸夫楼:大钟塔", "起始点", MB_OK);}if (t-1 == 4){MessageBox(NULL, "操场:跑跑步?", "起始点", MB_OK);}if (t-1 == 5){MessageBox(NULL, "计软楼:大本营", "起始点", MB_OK);}if (t-1 == 6){MessageBox(NULL, "长望楼:上机的地方", "起始点", MB_OK);}if (t-1 == 7){MessageBox(NULL, "北辰楼:好像一些老师的办公室?还有阶梯教室", "起始点", MB_OK);}if (t-1 == 8){MessageBox(NULL, "藕舫楼:数统院的楼,还有大物实验", "起始点", MB_OK);}if (t-1 == 9){MessageBox(NULL, "明德楼:最熟悉的楼吧", "起始点", MB_OK);}strcpy_s(a , G.vexs[t - 1].name);fillrectangle(r[t - 1][0] - 40, r[t - 1][1] - 40, r[t - 1][0] + 40, r[t - 1][1] + 40);//给确认的地点上点颜色jilu1 = t;//记录一下是哪个点 后面有用clickflag = 1;//起点设置完了,接下来点的点就是终点了}else if (t != button_judge(m.x, m.y, G) && clickflag == 1)//对这的话就是终点{t = button_judge(m.x, m.y, G);//记录位置if (t-1 == 0){MessageBox(NULL, "沁园:你住的地方", "终点", MB_OK);}if (t-1 == 1){MessageBox(NULL, "食堂:中老食堂,都吃过的吧", "终点", MB_OK);}if (t-1 == 2){MessageBox(NULL, "文德楼:拿快递拿快递!", "终点", MB_OK);}if (t-1 == 3){MessageBox(NULL, "逸夫楼:大钟塔", "终点", MB_OK);}if (t-1 == 4){MessageBox(NULL, "操场:跑跑步?", "终点", MB_OK);}if (t-1 == 5){MessageBox(NULL, "计软楼:大本营", "终点", MB_OK);}if (t-1 == 6){MessageBox(NULL, "长望楼:上机的地方", "终点", MB_OK);}if (t-1 == 7){MessageBox(NULL, "北辰楼:好像一些老师的办公室?还有阶梯教室", "终点", MB_OK);}if (t-1 == 8){MessageBox(NULL, "藕舫楼:数统院的楼,还有大物实验", "终点", MB_OK);}if (t-1 == 9){MessageBox(NULL, "明德楼:最熟悉的楼吧", "终点", MB_OK);}strcpy_s(b , G.vexs[t - 1].name);fillrectangle(r[t - 1][0] - 40, r[t - 1][1] - 40, r[t - 1][0] + 40, r[t - 1][1] + 40);//上色jilu2 = t;//记录int v0 = LocateVex(G, a);int v1 = LocateVex(G, b);//算起点和终点在图中的位置DIJ(G, v0, p);//启用DIJ算法算出最短路径setrop2(R2_XORPEN);setlinecolor(BLACK);setlinestyle(PS_SOLID,3);//设画笔来画线,但说实话这里应该不需要?因为我下面还有设置int flag = 0, lastpoint = 0,yici=0;//lastpoint是为了记录连线的时候,上一个点是啥,flag是为了表明这不是第一个点,是要连线的,yici是为了擦线做准备for (int i = 0; i < G.vexnum; i++){if (p[v1][i] == 1){lastpoint = i;//记录上一个点是啥flag = 1;}for (int j = 0; j < G.vexnum; j++){if (j!=lastpoint&&p[v1][j] == 1 && flag == 1 &&G.arcs[lastpoint][j].adj != max)//找最短路径上有哪些点,连线{setrop2(R2_COPYPEN);setlinecolor(RED);setlinestyle(PS_SOLID, 5);line(G.vexs[lastpoint].x, G.vexs[lastpoint].y, G.vexs[j].x, G.vexs[j].y);}}yici = 1;}if (yici==1){setrop2(R2_XORPEN);setlinecolor(LIGHTCYAN);//亮青色setlinestyle(PS_SOLID, 3);//画线:实线,10磅setfillcolor(WHITE);fillrectangle(r[jilu2 - 1][0] - 40, r[jilu2 - 1][1] - 40, r[jilu2 - 1][0] + 40, r[jilu2 - 1][1] + 40);//这里是因为设置了systempause 所以终点的涂色没继续下去,我这里给它上了个色MessageBox(NULL, "点击确认后按任意键继续", "提示", MB_OK);system("pause");//暂停看线,主要不暂停的话接下来删除直接就进行了,我要设置其他摁键来尽心删除操作有点麻烦setrop2(R2_XORPEN);//setlinecolor(LIGHTCYAN);//亮青色setlinestyle(PS_SOLID, 3);//画线:实线,10磅setfillcolor(WHITE);fillrectangle(r[jilu1 - 1][0] - 40, r[jilu1 - 1][1] - 40, r[jilu1 - 1][0] + 40, r[jilu1 - 1][1] + 40);fillrectangle(r[jilu2 - 1][0] - 40, r[jilu2 - 1][1] - 40, r[jilu2 - 1][0] + 40, r[jilu2 - 1][1] + 40);//把掐点换个终点颜色变回去for (int i = 0; i < G.vexnum; i++){if (p[v1][i] == 1){lastpoint = i;flag = 1;}for (int j = 0; j < G.vexnum; j++){if (j != lastpoint && p[v1][j] == 1 && flag == 1 && G.arcs[lastpoint][j].adj != max){setrop2(R2_COPYPEN);//这里的二元光栅一定要调回去,不然涂的线会千奇百怪,我没事,不过理论上不改也没事?setlinecolor(WHITE);setlinestyle(PS_SOLID, 5);line(G.vexs[lastpoint].x, G.vexs[lastpoint].y, G.vexs[j].x, G.vexs[j].y);setlinecolor(BLACK);setlinestyle(PS_SOLID);line(G.vexs[lastpoint].x, G.vexs[lastpoint].y, G.vexs[j].x, G.vexs[j].y);//地点之间的路重新打印一下RECT R3{ r[j][0] - 40, r[j][1] - 40, r[j][0] + 40, r[j][1] + 40 };drawtext(G.vexs[j].name, &R3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);RECT R4{ r[lastpoint][0] - 40, r[lastpoint][1] - 40, r[lastpoint][0] + 40, r[lastpoint][1] + 40 };//老原因,删线的时候会覆盖地点的名字,重新打印一下drawtext(G.vexs[lastpoint].name, &R4, DT_CENTER | DT_VCENTER | DT_SINGLELINE);}}}yici = 0;}clickflag = 0;//可以第二次点击起始点了setrop2(R2_XORPEN);setlinecolor(LIGHTCYAN);//亮青色setlinestyle(PS_SOLID, 3);//画线:实线,10磅setfillcolor(WHITE);fillrectangle(r[jilu2 - 1][0] - 40, r[jilu2 - 1][1] - 40, r[jilu2 - 1][0] + 40, r[jilu2 - 1][1] + 40);//给终点消掉颜色jilu1 = 0;jilu2 = 0;//jilu起点终点的归零}}break;FlushMouseMsgBuffer();//清空鼠标消息缓存 ,不删除的话会奇奇怪怪 我也没试过}}system("pause");closegraph();return 0;
}
大部分代码干嘛的,一些问题的解决我也都有写,有问题我来补充,好了我写课设报告去了,(要是一个学校一个课设哥们加点自己的心意吧,别直接抄了,还是自己写的来的实在)
演示
!](https://img-blog.csdnimg.cn/20201209215913373.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1JvYXJy,size_16,color_FFFFFF,t_70)
在这里插入图片描述
校园导游咨询系统(Dijkstra算法,图形化界面)相关推荐
- 【南邮操作系统实验】页面置换算法(FIFO、LRU、OPT)图形化界面(JavaFx)
页面置换算法图形化界面 前言 运行效果 源码 FIFO LRU OPT FXML界面 控制器 启动类 前言 其实以前操作系统实验的时候我写过了三份了:(命令行) 页面置换算法 (FIFO.LRU.OP ...
- 密码学--DES算法(图形化界面)python
密码学--DES算法python 要求 原理 主要功能界面 具体功能代码 源码 要求 网上搜索DES的源代码. 利用DES源代码实现下面功能: 给定某个Sbox的输入差分情况下,计算所有输入对和所有S ...
- 别找了,完整代码在这||校园导游咨询系统
juster数据结构实验2:校园导游咨询系统(附完整代码) 文章目录 juster数据结构实验2:校园导游咨询系统(附完整代码) 1.项目概述 1.1项目目标和主要内容 2.1[测试数据] 3.1[实 ...
- python使用界面-(八)Python 图形化界面设计
3.1.文本输入和输出相关控件:文本的输入与输出控件通常包括:标签(Label).消息(Message).输入框(Entry).文本框(Text).他们除了前述共同属性外,都具有一些特征属性和功能. ...
- 零基础学Python【二十三、图形化界面设计 】(基础一篇全,欢迎认领)
1.图形化界面设计的基本理解 当前流行的计算机桌面应用程序大多数为图形化用户界面(Graphic User Interface,GUI). 即通过鼠标对菜单.按钮等图形化元素触发指令,并从标签.对话框 ...
- python界面-(八)Python 图形化界面设计
3.1.文本输入和输出相关控件:文本的输入与输出控件通常包括:标签(Label).消息(Message).输入框(Entry).文本框(Text).他们除了前述共同属性外,都具有一些特征属性和功能. ...
- Java 入门-02-人机交互-图形化界面的小故事
人机交互的小故事 1981 年,IBM 和 wicrosoft 共同推出的 ms-dos 系统,在黑屏下面输入命令 1981 年 4 月 27 日,施乐公司推出了第一个有操作窗口的系统,引起了很大的轰 ...
- python中的图形界面设计_python图形化界面设计(tkinter)一全面介绍
3.3.单选按钮:(Radiobutton)是为了响应故乡排斥的若干单选项的单击事件以触发运行自定义函数所设的,该控件排除具有共有属性外,还具有显示文本(text).返回变量(variable).返回 ...
- Qt图形化界面—迷宫最短路径问题
这段时间为了日后的工作需要,遵循霍亚飞老师的<Qt Creator快速入门(第三版)>学了第一大章基础篇的知识,并根据所学的知识尝试性地将之前的迷宫最短路径问题进行了图形化界面的设计.由于 ...
最新文章
- 强烈推荐Oracle的入门心得
- MATLAB报错“Exception in thread FileDecorationCache request queue java.lang.OutOfMemoryError: Java “
- 上海交大25岁博士奶爸!6块腹肌,Science一作,人民日报都点赞了
- 浅谈javascript函数劫持
- 【C++】-- STL容器适配器之stack
- 从石器时代到硅器时代
- 2021年山东省职业院校技能大赛中职组“网络安全”赛项规程
- 报修下单上门维修小程序开发制作
- 有道云笔记markdown字体增大、生成目录
- php设置时区的两种方法
- 小程序+动易SF制作随手拍实例全景式操作(3)
- DeFi 入门必备:你需要了解的 DeFi 重要词语
- c语言经典案例 俄罗斯方块,C语言实现俄罗斯方块经典游戏课程设计
- 如何更改使用 Matplotlib 绘制的图形的大小?
- mmdetection 安装配置全过程
- matlab的多变量dmc源程序,基于MATLAB多变量DMC算法的仿真技术研究
- 【iOS】——==与isEqual方法
- 盘它:上线 2 个月碾压微信、抖音,音遇登顶 App Store 榜幕后的数据真相
- 自适应遗传算法 matlab,自适应遗传算法MATLAB代码
- Ubuntu 22.04 安装R语言及R studio
热门文章
- this version of the Java Runtime only recognizes class file versions up to 52.0 (unable to load clas
- iOS预审总被拒?腾讯教你提升iOS审核通过率!
- 堆内存的介绍及应用(含例子)
- 【C 练习】分开打印一个数的每一位数字
- 元宇宙与法律的梦幻联动 | Footprint Analytics
- 现在女生做什么赚钱,这8种职业非常有前途!
- 01-为什么要学爬虫-python小白爬虫入门教程
- 智能卡接口控制器(SIM)
- 2014卫士通A卷笔试题
- 自用款三星27寸曲面屏,包邮送到家!