zoukankan      html  css  js  c++  java
  • Dijkstra—校园景点游览问题

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define MAX 9999999
    using namespace std;
    typedef struct ArcCell{
        int length;//两点间的距离 
    }ArcCell, AdjMatrix[100][100];
    //景点 
    typedef struct {
        char sce_name[30];//景点名称
        int sce_num;//景点代号
        char sce_intro[200];//景点简介
    }Scenery;
    //图的数组表示法
    typedef struct {
        Scenery vexs[100];
        AdjMatrix arcs;
        int vexnum,arcnum;
    }MGraph; 
    //全局变量 
    int Path[100];//记录最短路径上的节点 
    int D[100];//记录节点到起始节点的距离 
    bool final[100];//标记该节点是否在路径上 
    //由风景名称获取风景在数组中的下标
    int GetSce(char sce_name[],MGraph G){ 
        int i;
        for(i=1;i<=G.vexnum;i++)
            if(strcmp(sce_name,G.vexs[i].sce_name)==0)return i;
        return -1;
    }
    //创建一个图 
    void Creat_Graph(MGraph &G){
        int i,j;
        int n1,n2,weight; //起始下标、终止下标、权值 
        char start[30], end[30];
        printf("■请输入景点个数: ");
        scanf("%d",&G.vexnum);//景点个数 
        printf("■请输入路的条数: ");
        scanf("%d",&G.arcnum);//路的条数 
        printf("
    ■输入景点信息(名称(char)、代号(int)、简介(char)). 
    ");
        for(i=1;i<=G.vexnum;i++){
            printf("第 %d 个景点: ",i);
            scanf("%s",G.vexs[i].sce_name);
            scanf("%d",&G.vexs[i].sce_num);
            scanf("%s",G.vexs[i].sce_intro);
        }
        printf("
    ■输入路况: 
    ");
        //先把二维数组给填一下 (相当于vexnum阶矩阵) 
        for(i=1;i<=G.vexnum;i++){
            for(j=1;j<=G.vexnum;j++){
                G.arcs[i][j].length = MAX;
            }
        }
        
        for(i=1;i<=G.arcnum;i++){
            printf("■弧头 & 弧尾 & 权值: ");
            scanf("%s",start);
            scanf("%s",end);
            n1 = GetSce(start,G);//经上面的景点信息获取景点的下标 
            n2 = GetSce(end,G);
            scanf("%d",&weight);
            G.arcs[n1][n2].length = weight;//矩阵双向的权值 
            G.arcs[n2][n1].length = weight;
        }
        printf("OK! 信息录入完毕!
    
    ");
    }
    //输出最短路径 
    void OutPutPath(MGraph G,bool find,int sn,int en){
        int i;
        int path[100];
        if(!find){
            printf("Sorry,无法找到从%s到%s的路.
    
    ",G.vexs[sn].sce_name,G.vexs[en].sce_name);
            return;
        }
        else {
            printf("
    ■■■%s 到 %s 最短路径上依次为: ",G.vexs[sn].sce_name,G.vexs[en].sce_name);
            path[0] = en;
            int k = 1,x = Path[en];
            while(x != sn){
                path[k++] = x;
                x = Path[x];
            }
            path[k] = sn;
            for(i=k;i>=0;i--){
                printf("%s",G.vexs[path[i]].sce_name);
                if(i!=0){
                    printf("");
                }
            }
            printf("
    ■■■其最短路径长度为: %d
    ",D[en]);
            printf("
    ");
        }
    }
    //迪杰斯特拉算法求最短路径 
    void Dijkstra(MGraph G,int sn,int en){
        int i;
        int v, min;//v--点的下标,min--节点离起始的距离 
        for(i=1; i<=G.vexnum; i++){
            final[i] = false;//用于记录是否在已确定的点的集合中 
            D[i] = G.arcs[sn][i].length;//每个点与起点的距离 
            //初始化记录最短路径的数组 
            if(D[i]!= MAX)//与起点相连 
                Path[i] = sn; 
            else//不与起点相连 
                Path[i] = 0;
        }
        D[sn] = 0;//初始化最开始的距离0 
        final[sn] = true;//起始节点在路径上 
        Path[sn] = sn;//记录最短路径上的第一个节点 
        bool find = false;//判断是否找到从起点到终点的路 
        while(1){
            min = MAX;
            v = -1;//先默认一个不存在的下标,下面根据各步的比较把最近点的下标赋给v 
            for(i = 1; i <= G.vexnum; i++){//找到当前位置与起点最近的点 
                if(final[i]==false && D[i] < min){//剩下的Ian还没连到最短路径上,而且点和最短路径的节点有通路 
                    v = i;
                    min = D[i];
                }
            }
            if(v==-1){//如果找不到最近的点,就没有必要求最短路径了,直接输出找不到路 
                find = false;
                break;
            }
            final[v] = true;
            for(i=1;i<=G.vexnum;i++){//修改每个点到起点的最近距离 ,若修改了,则说明通过v点修改点离起点更近了,此时记录Path[i] = v; 
                if(final[i]==false && (min + G.arcs[v][i].length <D[i])){
                    D[i] = min + G.arcs[v][i].length;
                    Path[i] = v;//这样就把下一个最近的点连接到路径上了 
                }
            } 
            if(v == en){//到达尾节点,结束循环 
                find = true;
                break;
            }
        }
        OutPutPath(G,find,sn,en);//输出最短路径 
    }
    int main(){
        while(1){
            MGraph G;
            char start[30],end[30],name[30],num;//起点集、终点集、名称集、景点对应的下标 
            int sn,en,choice;//起始点、终止点 
            printf("		■校园景点游览■
    "); 
            Creat_Graph(G);//创建图 
            while(1){
                printf("■用户操作:
    ");
                printf("(1)景点信息  (2)最短距离
    ");
                scanf("%d",&choice);
                if(choice == 1){
                    printf("■请输入要查找的景点的名称: ");
                    scanf("%s",name);
                    num = GetSce(name, G);
                    printf("名称:%s    代号:%d    简介:%s
    
    ",name,G.vexs[num].sce_num,G.vexs[num].sce_intro);    
                }else if(choice == 2){
                    printf("起点 & 终点:");
                    scanf("%s",start);
                    scanf("%s",end);
                    sn = GetSce(start,G);
                    en = GetSce(end,G);
                    if(sn==en)
                         printf("您输入的起始位置和终止位置相等,所以不必查询.
    
    ");
                    else 
                         Dijkstra(G,sn,en);//输出最短路径 
                }
                printf("■请输入您的选择:
    "); 
                printf("■(0)继续查询  (1)退出 
    
    ");
                int q;
                scanf("%d",&q);
                if(q){
                    printf("May the code be with u!");
                    exit(0);
                }
             }
         }
        return 0;
    }
  • 相关阅读:
    用Python查找数组中出现奇数次的那个数字
    python之路--MySQL多表查询
    python之路--MySQl单表查询
    python之路--MySQL 库,表的详细操作
    python之路--MySQL数据库初识
    python之路--线程的其他方法
    python之路--关于线程的一些方法
    python之路--管道, 事件, 信号量, 进程池
    python之路--进程内容补充
    python之路--操作系统介绍,进程的创建
  • 原文地址:https://www.cnblogs.com/cruelty_angel/p/10038763.html
Copyright © 2011-2022 走看看