校园导游系统(源码)

校园导游系统(源码)

#include
#include
#include
#include
#define MAXVEX 30
#define INFINITY 32767

typedef struct
{
	int num;  //地点权值
	char name[30]; //建筑名
	char build_describe[300]; //描述建筑
}Vextype;

typedef struct
{
	int arcs[MAXVEX][MAXVEX];
	Vextype vex[MAXVEX];
	int vexnum;
	int arcnum;
}MGraph;


int Index(MGraph *G, char name[]) //索引
{
	int i;
	for (i = 0; i < G->vexnum; i++)
	{
		if (!strcmp(name, G->vex[i].name))
			return i;
	}
	return -1;
}

//邻接矩阵创建无向图
void Creat(MGraph *G)
{
	FILE *fp;
	int i = 0,j = 0,k,m,index1,index2,weight;
	char name1[30], name2[30];
	fp=fopen("文件点.txt", "rt");  //文件中读取结点
	if (fp == NULL)
	{
		printf("文件为空,或者文件遭破坏,请呼叫工作人员。按任意退出...");
		getchar();
		exit(1);
	}
	while (fscanf(fp, "%s %s", G->vex[i].name,G->vex[i].build_describe) != EOF)
	{
		G->vex[i].num = i;
		i++;
	}
	fclose(fp);
	G->vexnum = i;

	for (m = 0; m < G->vexnum; m++)   //初始化邻接矩阵
		for (k = 0; k < G->vexnum; k++)
			G->arcs[m][k] = INFINITY;

	fp = fopen("文件边.txt", "rt");  //文件中读取边
	if (fp == NULL)
	{
		printf("文件为空,或者文件遭破坏,请呼叫工作人员。按任意退出...");
		getchar();
		exit(1);
	}
	while (fscanf(fp, "%s %s %d", name1,name2,&weight) != EOF)
	{
		index1 = Index(G, name1);
		index2 = Index(G, name2);
		G->arcs[index1][index2] = weight;
		G->arcs[index2][index1] = weight;
		j++;
	}   
	fclose(fp);
	G->arcnum = j;
}

void Display(MGraph *G)  //显示图信息
{
	int i, j;
	printf("校园各个路径的情况为:\n");
	for (i = 0; i < G->vexnum; i++)
		for (j = 0; j < i; j++)
		{
			if (G->arcs[i][j] != INFINITY)
				printf("%s<------>%s:%10dm\n", G->vex[i].name, G->vex[j].name, G->arcs[i][j]);
		}
}

void Search(MGraph *G)   //搜索建筑
{
	system("cls");
	char name[20];
	int num, i, j;
	printf("输入要查询地点:");
	scanf("%s", name);
	num = Index(G, name);
	printf("%s 简介:%s\n", name, G->vex[num].build_describe);
	for(i=0;i<G->vexnum;i++)
		if (i == num)
		{
			for (j = 0; j < G->vexnum; j++)
			{
				if (G->arcs[i][j] != INFINITY)
				{
					printf("%s<------>%s:%10dm\n", G->vex[num].name, G->vex[j].name, G->arcs[i][j]);
				}
			}
		}
}
//Dijkstra算法求从起点到终点的最短路径
void Dijkstra(MGraph *G, int start, int end, int dist[], int path[][MAXVEX])
{
	//dist记录各条最短路径长度,path数组记录对应路径上的各顶点
	int mindist, i, j, k, t = 1;
	for (i = 0; i < G->vexnum; i++)      //初始化
	{
		dist[i] = G->arcs[start][i];
		if (G->arcs[start][i] != INFINITY)
			path[i][1] = start;
	}
	path[start][0] = 1;
	for (i = 1; i < G->vexnum; i++)
	{
		mindist = INFINITY;
		for(j=0;j<G->vexnum;j++)  //选择最小权值路径
			if (!path[j][0] && dist[j] < mindist)
			{
				k = j;
				mindist = dist[j];
			}
		if (mindist == INFINITY)
			return;
		path[k][0] = 1;
		for (j = 0; j < G->vexnum; j++)  //修改路线
		{
			if (!path[j][0] && G->arcs[k][j] < INFINITY&&dist[k] + G->arcs[k][j] < dist[j])
			{
				dist[j] = dist[k] + G->arcs[k][j];
				t = 1;
				while (path[j][t] != 0)  //记录新的最短路径
				{
					path[j][t] = path[k][t];
					t++;
				}
				path[j][t] = k;
				path[j][t + 1] = 0;
			}
		}
	}
	for (i = 0; i < G->vexnum; i++)
		if (i == end)
			break;
	printf("从%s<------>%s的最短路线为:从%s", G->vex[start].name, G->vex[end].name, G->vex[start].name);
	for (j = 2; path[i][j] != 0; j++)
		printf("->%s", G->vex[path[i][j]].name);
	printf("->%s , 距离为: %dm\n", G->vex[end].name, dist[i]);
}


void Shortlink(MGraph *G) //寻找最短路线
{
	system("cls");
	char name[20];
	int start, end;
	int dist[MAXVEX], path[MAXVEX][MAXVEX] = { 0 };
	printf("请输入起点建筑:");
	scanf("%s", name);
	start = Index(G, name);
	printf("请输入终点建筑:");
	scanf("%s", name);
	end = Index(G, name);
	Dijkstra(G, start, end, dist, path);
}

void Prim(MGraph *G, int start)  //prim算法求最小生成树
{
	struct
	{
		int adjvex;
		int lowcost;
	}closedge[MAXVEX];
	int i, e, k, m, min;
	closedge[start].lowcost = 0;
	for(i=0;i<G->vexnum;i++)
		if (i!=start)
		{
			closedge[i].adjvex = start;
			closedge[i].lowcost = G->arcs[start][i];
		}
	for (e = 0; e < G->vexnum - 1; e++)
	{
		//选择最小权值的边
		min = INFINITY;
		for (k = 0; k < G->vexnum; k++)
		{
			if (closedge[k].lowcost != 0 && closedge[k].lowcost < min)
			{
				m = k;
				min = closedge[k].lowcost;
			}
		}
		printf("从%s<------>%s:%dm\n", G->vex[closedge[m].adjvex].name, G->vex[m].name, closedge[m].lowcost);
		closedge[m].lowcost = 0;
		//当m加入后,更新closedge数组信息
		for (i = 0; i < G->vexnum; i++)
		{
			if (i != m && G->arcs[m][i] < closedge[i].lowcost)
			{
				closedge[i].lowcost = G->arcs[m][i];
				closedge[i].adjvex = m;
			}
		}
	}
}

void Shortestconnect(MGraph *G)//求某个地点的最短联通路径
{
	system("cls");
	char name[20];
	int start;
	printf("请输入起点建筑:");
	scanf("%s", name);
	start = Index(G, name);
	Prim(G, start);
}

void Add_vex(MGraph *MG)  //添加新结点
{
	system("cls");
	FILE *fp;
	char name[20], describe[300];
	printf("请输入需要添加的地点:");
	scanf("%s", name);
	printf("请输入该地点的描述:");
	scanf("%s", describe);
	fp = fopen("文件点.txt", "at");
	if (fp == NULL)
	{
		printf("文件为空,或者文件遭破坏,请呼叫工作人员。按任意退出...");
		getchar();
		exit(1);
	}
	fprintf(fp, "%s %s\n", name,describe);
	printf("添加成功!");
	fclose(fp);
	Creat(MG); //更新文件内容,重新创建邻接矩阵
}

void Add_arcs(MGraph *MG)  //添加新边
{
	system("cls");
	FILE *fp;
	int weight,flag1=0,flag2=0,i;
	char start[20], end[20];
	printf("请输入起始地点:");
	scanf("%s", start);
	printf("请输入终止地点:");
	scanf("%s", end);
	printf("请输入地点之间的距离(单位m):");
	scanf("%d", &weight);
	for (i = 0; i < MG->vexnum; i++)
	{
		if (strcmp(start, MG->vex[i].name) == 0)
			flag1 = 1;
		if (strcmp(end, MG->vex[i].name) == 0)
			flag2 = 1;
	}
	if(flag1!=1&&flag2!=1)
	{
		printf("未找到与之匹配的地点!创建路径失败...");
		return;
	}
	fp = fopen("文件边.txt", "at");
	if (fp == NULL)
	{
		printf("文件为空,或者文件遭破坏,请呼叫工作人员。按任意退出...");
		getchar();
		exit(1);
	}
	fprintf(fp, "%s %s %d\n", start, end, weight);
	printf("添加成功!");
	fclose(fp);
	Creat(MG);   //更新文件内容,重新创建邻接矩阵
}

void Write_vex(MGraph *G)
{
	FILE *fp;
	int i, j,flag;
	fp = fopen("文件点.txt", "wt");
	if (fp == NULL)
	{
		printf("文件为空,或者文件遭破坏,请呼叫工作人员。按任意退出...");
		getchar();
		exit(1);
	}
	for (i = 0; i < G->vexnum; i++)
	{
		flag = 0;
		for (j = 0; j < G->vexnum; j++)
		{
			if (G->arcs[i][j] < INFINITY)
				flag = 1;
		}
		if(flag==1)
			fprintf(fp, "%s %s\n", G->vex[i].name,G->vex[i].build_describe);
	}
	fclose(fp);
}

void Write_arse(MGraph *G)
{
	FILE *fp;
	int i, j;
	fp = fopen("文件边.txt", "wt");
	if (fp == NULL)
	{
		printf("文件为空,或者文件遭破坏,请呼叫工作人员。按任意退出...");
		getchar();
		exit(1);
	}
	for (i = 0; i < G->vexnum; i++)
		for (j = 0; j <= i; j++)
		{
			if (G->arcs[i][j] < INFINITY)
			{
				fprintf(fp, "%s %s %d\n", G->vex[i].name, G->vex[j].name, G->arcs[i][j]);
			}
		}
	fclose(fp);
}

void Del_arcs(MGraph *G)
{
	system("cls");
	char name[20];
	int start, end;
	printf("请输入删除的起点名:");
	scanf("%s", name);
	start = Index(G, name);
	printf("请输入删除的终点名:");
	scanf("%s", name);
	end = Index(G, name);
	G->arcs[start][end] = INFINITY;
	G->arcs[end][start] = INFINITY;
	Write_arse(G);
	Write_vex(G);
	printf("删除成功!");
}

void Del_vex(MGraph *G)
{
	system("cls");
	char name[20];
	int num,i;
	printf("输入你要删除的地点:");
	scanf("%s", name);
	num = Index(G, name);
	for (i = 0; i < G->vexnum; i++)
	{
		G->arcs[num][i] = INFINITY;
		G->arcs[i][num] = INFINITY;
	}
	Write_arse(G);
	Write_vex(G);
	printf("删除成功!");
}

void Inputpasswd(char passwd[], int min, int ma_x)  //密码设置
{
	char s[20];
	char temp[2];
	int n;
	strcpy(s, " ");
	while (1)
	{
		while (1)
		{
			n = getch();
			if (n == 13)
			{
				break;
			}
			printf("*");
			memset(temp, 0, sizeof(temp));
			sprintf(temp, "%c", n);
			strcat(s, temp);
		}
		if (strlen(s) > ma_x + 1)
		{
			memset(s, 0, sizeof(s));
			printf("\n密码过长,请重新输入:");
			strcpy(s, " ");
			continue;
		}
		if (strlen(s) < min + 1)
		{
			memset(s, 0, sizeof(s));
			printf("\n密码过短,请重新输入:");
			strcpy(s, " ");
			continue;
		}
		break;
	}
	printf("\n");
}

char Set_passwd()
{
	FILE *fp;
	char passwd[10] = "123456";
	if ((fp = fopen("passward.txt", "wt")) == NULL)
	{
		printf("写文件出错,按任意键退出!");
		getch();
		exit(1);
	}
	fprintf(fp, "%s", passwd);
	fclose(fp);
	return passwd;

}


void Dfs(MGraph *G,int start, int end, int visit[], int path[], int len, int limit) //Dfs算法求简单路径
{
	int i;
	if (limit >= 0)
	{
		visit[start] = 1;
		path[len++] = start;
		if (start == end)
		{
			for (i = 0; i < len; i++)
			{
				if (i)
					printf("---->");
				printf("%s", G->vex[path[i]].name);
			}
			printf("\n");
		}
		else
		{   
			for (i = 0; i < G->vexnum; i++)
			{
				if (visit[i] != 1 && G->arcs[start][i] < INFINITE  && G->arcs[start][i])
				{
					Dfs(G, i, end, visit, path, len, limit-1);
				}
			}
		}
		visit[start] = 0;
	}
}

void All_path(MGraph *G)  //任意两地点的所有简单路径
{
	
	char name[20];
	int path[MAXVEX] = { 0 };
	int visit[MAXVEX] = { 0 };
	int start, end, len = 0, limit;
	system("cls");
	printf("请输入起点建筑:");
	scanf("%s", name);
	start = Index(G, name);
	printf("请输入终点建筑:");
	scanf("%s", name);
	end = Index(G, name);
	printf("由于路径过多,请输入中转次数限制:");
	scanf("%d", &limit);
	Dfs(G, start, end, visit, path, len, limit);
}


void Manage_menu(MGraph *MG)   //管理员菜单
{
	system("cls");
	int select;
	printf("请输入管理员密码:");
	Inputpasswd(Set_passwd(), 6, 9);
	printf("正在打开管理员系统...");
	Sleep(1000);
	system("cls");
	
	do
	{
		printf("\n\n\n\n\n\n\n");
		printf("\t\t\t\t*******************************************************\n");
		printf("\t\t\t\t*** |         1.增加新的地点信息                  | ***\n");
		printf("\t\t\t\t*** |           2.增加新的路径                    | ***\n");
		printf("\t\t\t\t*** |         3.删除某个地点信息                  | ***\n");
		printf("\t\t\t\t*** |           4.删除某条路径                    | ***\n");
		printf("\t\t\t\t*** |               0.退出                        | ***\n");
		printf("\t\t\t\t*******************************************************\n");
		printf("\n请输入选择:");
		scanf("%d", &select);
		switch (select)
		{
		case 1:
			Add_vex(MG);
			break;
		case 2:
			Add_arcs(MG);
			break;
		case 3:
			Del_vex(MG);
			break;
		case 4:
			Del_arcs(MG);
			break;
		case 0:
			return;
		}

	} while (1);
}

void menu(MGraph *MG) //菜单
{
	
	int select;
	Creat(MG);
	do
	{
		printf("\n\n\n\n\n\n\n");
		printf("\t\t\t\t**************西安邮电大学校园导游系统*****************\n");
		printf("\t\t\t\t*** |       1.显示各个建筑之间的基本信息          | ***\n");
		printf("\t\t\t\t*** |        2.查询单个建筑的基本信息             | ***\n");
		printf("\t\t\t\t*** |      3.查询任意两个地点的所有简单路径       | ***\n");
		//printf("\t\t\t\t*** |      4.查询任意两个地点的最短简单路径       | ***\n");
		printf("\t\t\t\t*** |       4.查询任意两地点的最短路径            | ***\n");
		printf("\t\t\t\t*** | 5.查询从某个地点出发到其它各地点的最佳布网  | ***\n");
		printf("\t\t\t\t*** |               6.管理员系统                  | ***\n");
		printf("\t\t\t\t*** |                  0.退出                     | ***\n");
		printf("\t\t\t\t*******************************************************\n");
		printf("\n请输入选择:");
		scanf("%d", &select);
		switch (select)
		{
		case 1:
			Display(MG);
			break;
		case 2:
			Search(MG);
			break;
		case 3:
			All_path(MG);
			break;
		/*case 4:
			Shortest_transfer(MG);
			break;*/
		case 4:
			Shortlink(MG);
			break;
		case 5:
			Shortestconnect(MG);
			break;
		case 6:
			Manage_menu(MG);
			break;
		case 0:return;
		}
	} while (1);
}

int main()
{
	MGraph MG;
	menu(&MG);
}

你可能感兴趣的:(c数据结构)