厦门大学校园导游系统(图论)

厦门大学校园导游系统(图论)

1、源代码
由之前的Dijstra算法和Floyd算法改造

#include <iostream>
#include<stdlib.h>
#include<queue>
#include<stdio.h>
using namespace std;
void pipei(int i);
using namespace std;
typedef int ArcCell;  //直接存放权值
typedef struct{
    ArcCell** arcs;   //邻接矩阵,二维数组
    int vexnum,arcnum;   //图中当前顶点数和弧数
    int *info;         //顶点向量,与邻接矩阵的数组下标对应,顶点的相关信息,可修改数据结构进行添加信息
}MGraph;
MGraph Graph;
//创建邻接矩阵
void CreatGraph(){
    Graph.vexnum=11;
    Graph.arcnum=12;

    Graph.arcs=(ArcCell**)malloc((Graph.vexnum+1)*sizeof(ArcCell*));  //动态开辟二维数组,0号单元不用
    Graph.info=(int*)malloc((Graph.vexnum+1)*sizeof(int));
    for(int i=0;i<=Graph.vexnum;i++)
        Graph.arcs[i]=(ArcCell*)malloc((Graph.vexnum+1)*sizeof(ArcCell));

    for(int i=0;i<=Graph.vexnum;i++)
        for(int j=0;j<=Graph.vexnum;j++)
            Graph.arcs[i][j]=0;                          //邻接矩阵全部置0,初始化
    Graph.arcs[1][2]=200;
    Graph.arcs[2][1]=200;

    Graph.arcs[1][3]=100;
    Graph.arcs[3][1]=100;

    Graph.arcs[3][5]=100;
    Graph.arcs[5][3]=100;

    Graph.arcs[3][4]=200;
    Graph.arcs[4][3]=200;

    Graph.arcs[4][6]=100;
    Graph.arcs[6][4]=200;

    Graph.arcs[6][8]=200;
    Graph.arcs[8][6]=200;

    Graph.arcs[4][7]=200;
    Graph.arcs[7][4]=200;

    Graph.arcs[8][9]=300;
    Graph.arcs[9][8]=200;

    Graph.arcs[7][9]=400;
    Graph.arcs[9][7]=200;

    Graph.arcs[7][10]=100;
    Graph.arcs[10][7]=200;

    Graph.arcs[9][11]=100;
    Graph.arcs[11][9]=200;

    Graph.arcs[10][11]=400;
    Graph.arcs[11][10]=200;
}

void view( )							      //浏览校园地图
{
	system("cls");
	printf("\t                     厦门大学                       \n");
	printf("\t --------------------------------------------------------|\n");
	printf("\t|       1       |       2       |      面朝大海,春暖花开  |\n");
	printf("\t|     演武场     |   演武大桥     |   ------------         |\n");
	printf("\t|      3         ----welcome-----                        |\n");
	printf("\t|   明培体育馆   ---------------   ‖--------------------  |\n");
	printf("\t|              |  5 科艺中心       |                      |\n");
	printf("\t|=========     |                  |                      |\n");
	printf("\t|        4     |        6         |    |8 芙蓉餐厅|       |\n");
	printf("\t|   嘉庚楼群    |     芙蓉湖       |                       |\n");
	printf("\t|        ‖     |                  |                      |\n");
	printf("\t=========  ==============================================|\n");
	printf("\t|-------                                                  |\n");
	printf("\t|       |‖ ‖                                              |\n");
	printf("\t|   图  |‖ ‖                                              |\n");
	printf("\t| 7 书  |‖ ‖                                              |\n");
	printf("\t|   馆  |‖ ‖                 ‖   |9 勤业餐厅|  ‖           |\n");
	printf("\t|======================================================== |\n");
	printf("\t|                --------------                           |\n");
	printf("\t|               |              |        11                |\n");
	printf("\t|    |  10  南校门    |               |芙蓉隧道|            |\n");
	printf("\t -------------------------------------------------------- \n");
	printf("\t                输入1遍历所在位置到景点的距离.               \n");
    printf("\t              输入2遍历所有位置的距离.                     \n");
}


//Dijkstra算法(从某个源点到其余各顶点的最短路径)
/* 最短路径类型定义 */
#define INF 10000  //定义无穷大
void Dijkstra(MGraph G, int v0)
{
    int set[G.vexnum+1];
    int min,i,j,v;
    int tmp[G.vexnum+1],k;
    int path1[G.vexnum+1];    //path[i]表示从源点到顶点i之间最短路径的前驱节点
    int dist1[G.vexnum+1];    //记录源点到顶点i之间的最短路径长度,dist的初值为arcs[v0][i]

    for(i=1;i<=G.vexnum;i++){//数组初始化
        if(G.arcs[v0][i])
            dist1[i]=G.arcs[v0][i];			//dist1[i]:v0到i的最短路径长度
        else dist1[i]=INF;                  //dist为无穷大
        set[i]=0;								//set[i]:标记数组,标记各顶点是否已加入路径
        if(G.arcs[v0][i])
            path1[i]=v0;						//path1[i]:保存从v0到vi路径上vi的前一个顶点
        else
            path1[i]=-1;						//代表v0到vi中间不经过任何顶点(可能不通,也可能是自身)
    }
    set[v0]=1;
    path1[v0]=-1;

    for(i=1;i<=G.vexnum;i++){					//初始化结束,关键操作开始(判断其余G1.vexnum-1个顶点)
        min=10000;
        for(j=1;j<=G.vexnum;j++){			//选出v0到剩余顶点中最短的一条路径
            if(!set[j] && dist1[j]<min){
                v=j;
                min = dist1[j];					//v0到剩余顶点的最短路径<v0, v>
            }
        }
        set[v]=1;								//将顶点v加入最短路径

        for(j=1;j<=G.vexnum;j++){				//判断v的加入是否会造就v0到剩余顶点的更短路径
            if(!set[j] && min && G.arcs[v][j] && (min+G.arcs[v][j])<dist1[j]){
                dist1[j]=min+G.arcs[v][j];
                path1[j]=v;
            }
        }
    }
    //输出路径
    for(i=1; i<=G.vexnum; i++){
        if(v0!=i)
        {
            pipei(v0);cout<<"到";pipei(i);cout<<"的路径为:";
            if(path1[i]==-1)
                printf("×");
            else{
                tmp[0] = 0;								//计数路径上的顶点个数
                if(v0!=i){
                    k = i;
                    do{
                        tmp[0]++;
                        tmp[tmp[0]] = k;
                        k = path1[k];
                    }while(path1[k]!=-1);
                }

                if(tmp[0]){
                    for(j=tmp[0];j>=1;j--)
                        pipei(tmp[j]);
                        //printf("%d ", G.info[tmp[j]]);   //tmp数组记录路径并输出
                }
            }
            printf(",路程为:");
            if(dist1[i]==INF)
                printf("∞\n");
            else
                printf("%2d\n", dist1[i]);
        }
    }
}

void pipei(int i){
    switch(i)
    {
        case  1  :printf("演武场.");break;
        case  2  :printf("演武大桥.");break;
        case  3  :printf("明培体育馆.");break;
        case  4  :printf("嘉庚楼群.");break;
        case  5  :printf("科艺中心.");break;
        case  6  :printf("芙蓉湖.");break;
        case  7  :printf("图书馆.");break;
        case  8  :printf("芙蓉餐厅.");break;
        case  9  :printf("勤业餐厅.");break;
        case  10 :printf("南校门.");break;
        case  11 :printf("芙蓉隧道.");break;
    }
}
//Floyd算法求各顶点之间最短路径
void Floyd(MGraph G)
{
    int i, j, k;
    int path[20][G.vexnum+1];
    int dist[20][G.vexnum+1];
    int tmp[G.vexnum+1];

    for(i=1;i<=G.vexnum;i++){   //赋初值
        for(j=1; j<=G.vexnum; j++){
            if(G.arcs[i][j])
                dist[i][j] = G.arcs[i][j];
            else dist[i][j]=INF;
            path[i][j] = -1;
        }
    }

    for(k=1;k<=G.vexnum;k++){							//以k为中间点检测各对顶点间距离
        for(i=1;i<=G.vexnum;i++){
            for(j=1;j<=G.vexnum;j++){
                if(i!=j && dist[i][k]!=INF && dist[k][j]<INF && dist[i][k]+dist[k][j]<dist[i][j])
                {
                    dist[i][j] = dist[i][k] + dist[k][j];
                    path[i][j] = k;
                }
            }
        }
    }

    //输出各对顶点之间路径
    for(i=1;i<=G.vexnum;i++){
        for(j=1; j<=G.vexnum; j++){
            if(i!=j){
                pipei(i);cout<<"到";pipei(j);cout<<"的最短路径为:";
                //printf("%d 到 %d 的最短路径为:", G.info[i], G.info[j]);

                if(dist[i][j]!=INF){
                    pipei(i);
                    //printf("%d ", G.info[i]);
                    k = i;
                    while(path[k][j]!=-1){
                        pipei(path[k][j]);
                        //printf("%d ", G.info[path[k][j]]);
                        k = path[k][j];
                    }
                    pipei(j);
                    //printf("%d ", G.info[j]);
                }
                else
                    printf("×");

                printf(",路程为:");
                if(dist[i][j]==INF)
                    printf("∞\n");
                else
                    printf("%d\n", dist[i][j]);
            }
        }
    }
}

int main() {
    view();
    int a,b;
    scanf("%d",&b);
    CreatGraph();
    if(b==1) {
        printf("输入现在所在的位置:");
        scanf("%d", &a);
        Dijkstra(Graph, a);
    }else if(b==2) {
        printf("\n");
        Floyd(Graph);
    }
    return 0;
}

2、界面(不太友好啊)
在这里插入图片描述

发布了26 篇原创文章 · 获赞 39 · 访问量 1813

猜你喜欢

转载自blog.csdn.net/matafeiyanll/article/details/103153595