一星期的课设,前几天忙着刷题,,课设只做了一天半。。好多功能没有实现,封装也有问题。。时间来不及了。。
#include<bits/stdc++.h> #include<conio.h> const int MinData=-999999; const int INF=0x3f3f3f3f; using namespace std; struct Scenic_node{ int id; char name[50]; char function[100]; char introductin[2000]; int nxt[2000]; }; struct Edge_of_krus{ int u,v,w; Edge_of_krus(){} Edge_of_krus(int uu,int vv,int ww):u(uu),v(vv),w(ww){} bool operator<(const Edge_of_krus & a)const{ return w>a.w; } }; struct Edge_of_dfs{ int to,next,w; }; /*struct min_heap{//最小堆 typedef struct HeapStruct{ int *p; int size; int capacity; } *MinHeap; MinHeap H; int IsFull(MinHeap H){ return (H->size == H->capacity) ? 1 : 0; } int IsEmpty(MinHeap H){ return (H->size == 0) ? 1 : 0; } void PrintValue(MinHeap H){ int i; printf("最小堆中的元素依次为:"); for (i = 1; i <= H->size; i++) printf("%d ", H->p[i]); printf("\n"); } MinHeap Init_MinHeap(int MaxSize){ MinHeap H = (MinHeap)malloc(sizeof(HeapStruct)); H->p = (int*)malloc((MaxSize + 1) * sizeof(int)); H->p[0] = MinData; H->size = 0; H->capacity = MaxSize; return H; } void Insert(MinHeap H, int data){ int i; if (IsFull(H)){ printf("最小堆已满,无法插入元素"); return; } for (i = ++H->size; data < H->p[i / 2]; i /= 2) H->p[i] = H->p[i / 2]; H->p[i] = data; } int Delete(MinHeap H){ int minvalue , lastvalue, child, parent; if (IsEmpty(H)){ printf("最小堆已满,无法删除元素"); return -999; } minvalue = H->p[1]; lastvalue = H->p[H->size--]; for (parent = 1; 2 * parent <= H->size; parent = child){ child = 2 * parent; if (child != H->size && H->p[child + 1] < H->p[child]) child++; if (lastvalue < H->p[child]) break; else H->p[parent] = H->p[child]; } H->p[parent] = lastvalue; return minvalue; } void BuildMinHeap(MinHeap H, int N){ int i, num, parent, child, root, lastvalue; if (N > H->capacity){ printf("要创建的元素个数超过堆的最大容量,创建失败"); return; } for (i = 1; i <= N; i++){ printf("请输入要插入的元素值:"); scanf("%d", &num); H->p[i] = num; } H->size = N; root = N / 2; while (root){ lastvalue = H->p[root]; for (parent = root; 2 * parent <= H->size; parent = child){ child = 2 * parent; if (child != H->size && H->p[child + 1] < H->p[child]) child++; if (lastvalue < H->p[child]) break; else H->p[parent] = H->p[child]; } H->p[parent] = lastvalue; --root; } } }p_q; */ struct Fase{ void Main_Interface(){ puts("/*************主界面***************/"); printf("-------------------------------------\n"); puts("1.前台服务"); puts("2.后台管理"); puts("0.退出系统"); puts("请输入你的选择:"); } void Reception_Interface(){ puts("/*************前台服务***************/"); printf("-------------------------------------\n"); puts("1.景点信息查询"); puts("2.问路查询"); puts("3.铺设网线"); puts("0.返回"); puts("请输入你的选择:"); } void Query_Node_Interface(){ puts("/*************前台-景点信息查询***************/"); printf("-------------------------------------\n"); puts("1.根据景点名称查询"); puts("2.根据景点功能查询"); puts("0.返回"); puts("请输入你的选择:"); } void Query_Path_Interface(){ puts("/*************前台-路径查询***************/"); printf("-------------------------------------\n"); puts("1.两个景点之间的最短路"); puts("2.两个景点之间所有路"); puts("0.返回"); puts("请输入你的选择:"); } void Backstage_Interface(){ puts("/*************后台***************/"); printf("-------------------------------------\n"); puts("1.修改一个已有景点的相关信息"); puts("2.增加一个新景点及其相关信息"); puts("3.增加一条新的路径"); puts("4.删除一个景点及其相关信息"); puts("5.删除一条路径"); puts("0.返回"); puts("请输入你的选择:"); } }face; struct Date{ Scenic_node node[1000];//最多1000个点 int flag[1000];//标记点是否存在 Edge_of_krus edge1[5000];//最多5000条边 Edge_of_dfs edge2[5000]; int dis[1000][1000];//邻接矩阵 char passwd[50]; int size_v,size_e,tot1,tot2,head[1000];//链表 inline void init(){ strcpy(passwd,"123456"); memset(node,0,sizeof node); memset(edge1,0,sizeof edge1); memset(edge2,0,sizeof edge2); memset(dis,0,sizeof dis); memset(head,-1,sizeof head); tot1=tot2=0; } inline addedge1(int u,int v,int w){//往最小生成树中加边 edge1[tot1++]=Edge_of_krus(u,v,w); } inline addedge2(int u,int v,int w){//往链表中加边 edge2[tot2].to=v; edge2[tot2].w=w; edge2[tot2].next=head[u]; head[u]=tot2++; } int vis[1000]; void dfs(int u,int fa){ vis[u]=1; printf("%d ",u); for(int i=head[u];i!=-1;i=edge2[i].next){ int v=edge2[i].to; if(v==fa || vis[v]) continue; dfs(v,u); } } void debug(){ int tmp_v=0,tmp_e=0; for(int i=1;i<=size_v;i++)//统计有多少结点 if(flag[i]) tmp_v++; for(int i=1;i<=size_v;i++)//统计有多少边 for(int j=i+1;j<=size_v;j++) if(dis[i][j]) tmp_e++; printf("%d %d\n",tmp_v,tmp_e);//输出修改后的结点个数,边个数 for(int i=1;i<=size_v;i++)//输出结点信息 printf("%s %s %s\n",node[i].name,node[i].function,node[i].introductin); for(int i=1;i<=size_v-1;i++) for(int j=i+1;j<=size_v;j++) if(dis[i][j]) printf("%d %d %d\n",i,j,dis[i][j]); //按dfs序遍历所有的边 dfs(1,1); } void read(){ init(); puts("正在导入数据"); freopen("map.txt","r",stdin); scanf("%d %d",&size_v,&size_e); for(int i=1;i<=size_v;i++){//读入顶点信息 node[i].id=i; flag[i]=1; scanf("%s %s %s",node[i].name,node[i].function,node[i].introductin); pre_kmp(i); } for(int i=1;i<=size_e;i++){//读入边的信息 int u,v,w; scanf("%d%d%d",&u,&v,&w); dis[u][v]=dis[v][u]=w; addedge1(u,v,w); addedge1(v,u,w); addedge2(u,v,w); addedge2(v,u,w); } freopen("CON","r",stdin); } void write(){ int tmp_v=0,tmp_e=0; freopen("map1.txt","w",stdout); for(int i=1;i<=size_v;i++)//统计有多少结点 if(flag[i]) tmp_v++; for(int i=1;i<=size_v;i++)//统计有多少边 for(int j=i+1;j<=size_v;j++) if(dis[i][j]) tmp_e++; printf("%d %d\n",tmp_v,tmp_e);//输出修改后的结点个数,边个数 for(int i=1;i<=size_v;i++)//输出结点信息 printf("%s %s %s\n",node[i].name,node[i].function,node[i].introductin); for(int i=1;i<=size_v-1;i++) for(int j=i+1;j<=size_v;j++) if(dis[i][j]) printf("%d %d %d\n",i,j,dis[i][j]); puts("数据写回成功!"); freopen("CON","w",stdout); } void dijkstra(int u,int v){ int vis[1010],pre[1010],lowcost[1010]; for(int i=1;i<=size_v;i++) { lowcost[i]=INF;vis[i]=0;pre[i]=-1; } lowcost[u]=0; for(int j=1;j<=size_v;j++){ int k=-1,Min=INF; for(int i=1;i<=size_v;i++){ if(!vis[i] && lowcost[i]<Min && flag[i]){ Min=lowcost[i]; k=i; } } if(k==-1 || k==v) break; vis[k]=1; for(int i=1;i<=size_v;i++) if(!vis[i] && dis[k][i] && lowcost[k]+dis[k][i]<lowcost[i]){ lowcost[i]=lowcost[k]+dis[k][i]; pre[i]=k; } } //输出路径 int end=v; stack<int>stk; stk.push(v); while(pre[v]!=-1){ stk.push(pre[v]); v=pre[v]; } while(!stk.empty()){ int tmp=stk.top(); printf("%s-->",node[tmp].name); stk.pop(); } printf("该路径总长度为:%d\n",lowcost[end]); } int used[1010],a[1010],now;//每次dfs到v结点时就打印一条路径 void print_all(int u,int end,int pre,int w){ if(u==end){ for(int i=1;i<=now;i++) printf("%s-->",node[a[i]].name); printf("%s-->该路径的总长度为:%d\n",node[end].name,w); return; } used[u]=1; a[++now]=u; for(int i=head[u];i!=-1;i=edge2[i].next){ int v=edge2[i].to; if(v==pre|| flag[v]==0 || used[v] || !dis[u][v]) continue; print_all(v,end,u,w+dis[u][v]); } used[u]=0;//回溯 now--; } void pre_kmp(int v){ int m,i,j; j=node[v].nxt[0]=-1; i=0; m=strlen(node[v].function); while(i<m){ while(j!=-1 && node[v].function[i]!=node[v].function[j]) j=node[v].nxt[j]; node[v].nxt[++i]=++j; } } void new_node(char *name,char *function,char *intro){ node[++size_v].id=size_v; flag[size_v]=1; strcpy(node[size_v].name,name); strcpy(node[size_v].function,function); strcpy(node[size_v].introductin,intro); pre_kmp(size_v); } void new_road(int u,int v,int w){ dis[u][v]=dis[v][u]=w; addedge1(u,v,w); addedge1(v,u,w); addedge2(u,v,w); addedge2(v,u,w); } void delete_node(int index){ flag[index]=0;//直接屏蔽该点即可 } void delete_path(int u,int v){//直接屏蔽掉该边即可 dis[u][v]=dis[v][u]=0; } int f[1010]; vector<Edge_of_krus> vec; int find(int x){ if(f[x]==-1) return x; return f[x]=find(f[x]); } void kruskal(){ int cnt=0,ans=0,size=0; vec.clear(); priority_queue<Edge_of_krus> pq; memset(f,-1,sizeof f); for(int i=1;i<=size_v;i++) size+=flag[i]; for(int i=1;i<=tot2;i++){ int u=edge1[i].u; int v=edge1[i].v; if(flag[u] && flag[v]) pq.push(edge1[i]); } while(!pq.empty()){ Edge_of_krus tmp=pq.top(); pq.pop(); int u=tmp.u,v=tmp.v,w=tmp.w; int t1=find(u); int t2=find(v); if(t1!=t2){ ans+=w; f[t1]=t2; vec.push_back(tmp); } if(vec.size()==size-1) break; } for(int i=0;i<vec.size();i++) printf("线路起点:%s --> 线路终点:%s\n",node[vec[i].u].name,node[vec[i].v].name); printf("网线总长度为%d\n",ans); } void kmp(char *function){//字符串function在模式串上跑 puts("拥有该功能的景点有:"); int i,j,n; n=strlen(function); for(int id=1;id<=size_v;id++) if(flag[id]){ i=j=0; int m=strlen(node[id].function); while(i<m){ while(j!=-1 && node[id].function[i]!=function[j]) j=node[id].nxt[j]; ++i;++j; if(j>=n){ printf(" %s",node[id].name); break; } } } puts(""); } }dt; struct Backstage{//后台管理程序 void check(char *password, int min, int max) { int num = 0; char ch; while (1) { ch = getch(); if (ch == '\r')break; else if (ch == '\b') { if (num > 0) { printf("\b \b"); num--; }continue; } printf("*"); if (num > max)break; password[num++] = ch; } password[num] = 0; } void load(){//登陆程序 int op,tot=0,flag=0; char password[1000]; while(tot<3){ puts("请输入密码"); check(password,0,6); if(!strcmp(password,dt.passwd)){ flag=1; break; } puts("密码输入错误,请再次输入"); tot++; } if(flag==0){ puts("输入密码连续错三次,退出后台管理系统"); return; } puts("密码输入成功!"); while(1){ face.Backstage_Interface(); scanf("%d",&op); if(op==1) Change_introduction(); else if(op==2) Add_node(); else if(op==3) Add_path(); else if(op==4) Delete_node(); else if(op==5) Delete_path(); else return; } } int Get_index(char *name){//返回该景点的标号 int flag=0; for(int i=1;i<=dt.size_v;i++) if(strcmp(dt.node[i].name,name)==0 && dt.flag[i]){ flag=1; return i; } if(flag==0) return -1; } void Change_introduction(){//改变景点介绍 char name[50],intro[2000]; puts("请输入景点名字"); scanf("%s",name); int i=Get_index(name); if(i==-1){ puts("没有这个景点"); return; } puts("请输入修改的信息"); scanf("%s",intro); strcpy(dt.node[i].introductin,intro); puts("修改完成"); } void Add_node(){//增加新景点 char name[50],function[1000],intro[2000]; puts("请输入景点名字"); scanf("%s",name); puts("请输入景点功能"); scanf("%s",function); puts("请输入景点介绍"); scanf("%s",intro); dt.new_node(name,function,intro); puts("修改完成"); } void Add_path(){//增加新路径 char name1[50],name2[50]; int w; puts("请输入新路径的起点,终点和权值"); scanf("%s %s %d",name1,name2,&w); int index1=Get_index(name1),index2=Get_index(name2);//找到两个节点在数据库中的下标 if(index1==-1 || index2 ==-1){ puts("节点不存在"); return; } dt.new_road(index1,index2,w); } void Delete_node(){//删掉某个顶点 char name[50]; puts("请输入要删除的结点"); scanf("%s",name); int index=Get_index(name); if(index==-1) { puts("该节点不存在"); return; } dt.delete_node(index); } void Delete_path(){//删掉一条路径 char name1[50],name2[50]; puts("请输入要删除的边"); scanf("%s %s",name1,name2); int index1=Get_index(name1); int index2=Get_index(name2); if(index1==-1 || index2==-1){ puts("结点不存在"); return; } dt.delete_path(index1,index2); } }bt; struct Reception{//前台服务程序 void start(){//启动前台服务程序 int op,op1; while(1){ face.Reception_Interface(); scanf("%d",&op); if(op==1){//查询景点信息 face.Query_Node_Interface(); scanf("%d",&op1); if(op1==1) Get_information(); else if(op1==2) Get_Scenic_node(); } else if(op==2){//问路查询 face.Query_Path_Interface(); scanf("%d",&op1); if(op1==1) Get_Path(); else if(op1==2) Query_Path(); } else if(op==3) Optimal_Routing_Path(); else if(op==0) //返回 return; else puts("请输入正确选项"); } } int Get_index(char *name){//返回该景点的标号 int flag=0; for(int i=1;i<=dt.size_v;i++) if(strcmp(dt.node[i].name,name)==0 && dt.flag[i]){ flag=1; return i; } if(flag==0) return -1; } void Get_information(){//输入名字输出信息 char name[50]; puts("请输入名字"); scanf("%s",name); int i=Get_index(name); if(i==-1){ puts("没有这个景点"); return; } printf("%s\n",dt.node[i].introductin); } inline void Get_Scenic_node(){//输入功能输出所有有该信息的功能 char function[50]; puts("请输入要查找的功能"); scanf("%s",function); dt.kmp(function); } void Get_Path(){//输入两个景点名字,输出最短路 char name1[50],name2[50]; puts("请输入两个景点的名字"); scanf("%s %s",name1,name2); int u=Get_index(name1),v=Get_index(name2); if(u==-1 || v==-1) { puts("景点不存在"); return; } dt.dijkstra(u,v); } void Query_Path(){//输出两个顶点之间的所有路径 char name1[50],name2[50]; puts("请输入两个景点的名字"); scanf("%s%s",name1,name2); int u=Get_index(name1),v=Get_index(name2); if(u==-1 || v==-1){ puts("景点不存在"); return; } dt.now=0; dt.print_all(u,v,0,0); } void Optimal_Routing_Path(){//铺网线 puts("正在为您铺设网线"); dt.kruskal(); } }rt; int main(){ int op; dt.read();//读入数据 while(1){ face.Main_Interface();//进入程序后进入主界面 scanf("%d",&op); if(op==1) rt.start(); else if(op==2) bt.load(); else if(op==0) {//写回数据,退出 dt.write(); puts("感谢您的使用"); break; } else puts("请输入正确选项"); } return 0; }