课设。。

一星期的课设,前几天忙着刷题,,课设只做了一天半。。好多功能没有实现,封装也有问题。。时间来不及了。。

#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;
}

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/10154597.html