数据结构(C语言) 实验---图及其应用

[问题描述]
运用Dijkstra算法求最短路径。
1、将导游图看作一张带权无向图,顶点表示公园的各个景点,边表示各景点之间的道路,边上的权值表示距离,选择适当的数据结构。
2、求大门到各个景点之间的一条最短路径。

#include<iostream>
#include<string>

using namespace std;

#define MAX 1000000  //表示极大值∞
#define max 10

bool S[max];   //记录从源点V0到终点Vi是否已经确定为最短路径,确定了记true,否则记false
int Path[max]; //记录从源点V0到终点Vi的当前最短路径上终点Vi的直接前驱顶点序号,若V0到Vi之间有边前驱为V0否则为-1 
int D[max];  //记录源点到终点之间最短路径的长度,存在记V0到Vi的边的权值,否则记为MAX   
    
typedef struct
{
    string vexs[max];       //顶点表
    int arcs[max][max];      //邻接矩阵        
    int vexnum, arcnum;    //图当前点数和边数

}AMGraph;

//利用迪杰斯特拉算法求最短路径
void ShortestPath_DIJ(AMGraph &G, int v0)
{//使用迪杰斯特拉算法求有向网G中的V0 定点到其余顶点的最短路径
    int n = G.vexnum;//顶点数
    for (int v = 0; v < n; v++)//n个顶点依次初始化
    {
        S[v] = false;//S初始化为空集
        D[v] = G.arcs[v0][v];//将v0到各个终点的最短路径长度初始化为边上的权值
        if (D[v] < MAX)
            Path[v] = v0;//如果v0和v之间有边,则将v的前驱初始化为v0
        else
            Path[v] = -1;//如果v0和v之间无边,则将v的前驱初始化为-1
    }
    S[v0] = true; //将v0加入s
    D[v0] = 0;//源点到源点的权值为0
    //---------初始化结束,开始主循环,每次求得v0到某个顶点的最短路径,将v加到S数组
    for (int i = 1; i < n; i++)//依次对其余n-1个顶点进行计算
    {
        int    min = MAX;
        int v = v0;
        for (int w = 0; w < n; w++)
        {
            if (!S[w] && D[w] < min)
            {//选择一条当前最短路径,终点为v
                v = w;
                min = D[w];
            }
            S[v] = true;//将v加到s集合中
            for (int w = 0; w < n; w++)
            {//更新从v0出发到集合V-S上所有顶点的最短路径长度
                if (!S[w] && (D[v] + G.arcs[v][w] < D[w]))
                {
                    D[w] = D[v] + G.arcs[v][w];//更新D[w]
                    Path[w] = v;//更改w的前驱为v
                }
            }
        }
    }
}

//背景函数
void backGround()
{
    cout << "|*****************************************************************|" << endl;
    cout << "    |---------------------------软院地图--------------------|"     << endl;
    cout << "|*****************************************************************|" << endl;
    cout << "|           ⑦                                          单位:米  |" << endl;
    cout << "|         行政楼                                                  |" << endl;
    cout << "|            ◎                                      ⑧           |" << endl;
    cout << "|           ↗↖                                   九,十栋        |" << endl;
    cout << "|  ③  200╱    ╲                                   ◎           |" << endl;
    cout << "|  大   ↙        ╲ 150                            ↗ ↖         |" << endl;
    cout << "|  门 ◎            ╲       ①               160 ╱     ╲ 200   |" << endl;
    cout << "|      ↖150          ╲    软件          ⑥    ╱         ╲     |" << endl;
    cout << "|    ④  ↘    140      ↘   楼   200  一食堂 ↙     230     ↘   |" << endl;
    cout << "|   操场   ◎-------------→◎←--------------→◎←---------→◎ |" << endl;
    cout << "|            ↖         ↗ ↖              ↗ ↖             ↗② |" << endl;
    cout << "|          100 ╲     ╱     ╲ 125      ╱     ╲ 150     ╱  二 |" << endl;
    cout << "|                ↘ ↙ 100     ╲      ╱135      ╲     ╱145 食 |" << endl;
    cout << "|                  ◎            ↘  ↙             ↘ ↙      堂 |" << endl;
    cout << "|            ⑨天龙人学院          ◎                 ◎          |" << endl;
    cout << "|                             ⑩ 六栋           ⑤  遗址          |" << endl;
    cout << "|                                                                 |" << endl;
    cout << "|*****************************************************************|" << endl;

}

//主菜单
void menu()
{
    cout << "|*****************************************************************|" << endl;
    cout << "|----------------------------软院导游小程序-----------------------|" << endl;
    cout << "    |*********************************************************|" << endl;
    cout << "        |--------------------1-地点信息查询--------------|" << endl;
    cout << "        |--------------------2-最短路径查询--------------|" << endl;
    cout << "        |--------------------3-显示软院视图--------------|" << endl;
    cout << "        |------------------- 4-退出导游程序------ -------|" << endl;
    cout << "|*****************************************************************|" << endl;
    cout << ">>>请选择:";
}

//景点信息查询二级菜单
void jmenu()
{
    cout << "|*****************************************************************|" << endl;
    cout << "    |-------------------------地点信息查询------------------------|" << endl;
    cout << "    |***********************************************************|" << endl;
    cout << "      |----------------------1-软件楼介绍---------------------| " << endl;
    cout << "      |----------------------2-二食堂介绍---------------------| " << endl;
    cout << "      |----------------------3-大门介绍-----------------------| " << endl;
    cout << "      |----------------------4-操场介绍-----------------------| " << endl;
    cout << "      |----------------------5-遗址介绍-----------------------| " << endl;
    cout << "      |----------------------6-一食堂介绍---------------------| " << endl;
    cout << "      |----------------------7-行政楼介绍---------------------| " << endl;
    cout << "      |----------------------8-九,十栋介绍--------------------| " << endl;
    cout << "      |----------------------9-天龙人学院介绍-----------------| " << endl;
    cout << "      |--------------------- 10-六栋介绍----------------------| " << endl;
    cout << "|*****************************************************************|" << endl;
    cout << ">>>请要查询的地点编号:";
}

//最短路径查询二级菜单
void pmenu()
{
    cout << "|*****************************************************************|" << endl;
    cout << "    |-------------------------最短路径查询------------------------|" << endl;
    cout << "    |*******************此处为大门到各点最短路径******************|" << endl;
    cout << "      |----------------------1-软件楼-----------------------| " << endl;
    cout << "      |----------------------2-二食堂-----------------------| " << endl;
    cout << "      |----------------------3-大门-------------------------| " << endl;
    cout << "      |----------------------4-操场-------------------------| " << endl;
    cout << "      |----------------------5-遗址-------------------------| " << endl;
    cout << "      |----------------------6-一食堂-----------------------| " << endl;
    cout << "      |----------------------7-行政楼-----------------------| " << endl;
    cout << "      |----------------------8-九,十栋----------------------| " << endl;
    cout << "      |----------------------9-天龙人学院-------------------| " << endl;
    cout << "      |--------------------- 10-六栋------------------------| " << endl;
    cout << "|*****************************************************************|" << endl;
    cout << ">>>请要查询的地点编号:";//
}

int main()
{
     //初始化操作
    AMGraph amg = { { "软件楼","二食堂","大门","操场","遗址",
                      "一食堂",    "行政楼",    "九,十栋",   "天龙人学院", "六栋" },
        //-1代表两边不相连,权值无限大
        //邻接矩阵   /* 软  二  门  场  遗  一  政  九  天  六*/    
                     {{MAX,MAX,MAX,140,MAX,200,150,MAX,100,125 },
                      {MAX,MAX,MAX,MAX,145,230,MAX,100,MAX,MAX },
                      {MAX,MAX,MAX,150,MAX,MAX,200,MAX,MAX,MAX },
                      {140,MAX,150,MAX,MAX,MAX,MAX,MAX,100,MAX },
                      {MAX,145,MAX,MAX,MAX,150,MAX,MAX,MAX,MAX },
                      {200,230,MAX,MAX,150,MAX,MAX,160,MAX,135 },
                      {150,MAX,200,MAX,MAX,MAX,MAX,MAX,MAX,MAX },
                      {MAX,200,MAX,MAX,MAX,160,MAX,MAX,MAX,MAX },
                      {100,MAX,MAX,100,MAX,MAX,MAX,MAX,MAX,MAX },
                      {125,MAX,MAX,MAX,MAX,135,MAX,MAX,MAX,MAX }
                      },10,14};
    int f, ff;
    int start, end;
    while (true)
    {
        cout << endl;
        menu();
        cin >> f;
        if (f == 1)
        {
            jmenu();
			cin>>ff;
            cout << "|-----------------------地点介绍-------------------| " << endl;
            if (ff == 1)
                cout << "暂无" << endl;
            else if (ff == 2)
                cout <<"                       暂无" << endl;
            else if (ff == 3)
                cout <<"                       暂无" << endl;
            else if(ff == 4)
                cout <<"                       暂无" << endl;
            else if (ff == 5)
                cout <<"                       暂无" << endl;
            else if (ff == 6)
                cout <<"                       暂无" << endl;
            else if (ff == 7)
                cout <<"                       暂无" << endl;
            else if (ff == 8)
                cout <<"                       暂无" << endl;
            else if (ff == 9)
                cout <<"                       暂无" << endl;
            else if (ff == 10)
                cout <<"                       暂无" << endl;
            cout << "|-------------------------------------------------|" << endl;
        }
        else if (f == 2)
        {
            pmenu();
            cin  >> end;
            ShortestPath_DIJ(amg, 3 - 1);
            int temp = end-1;
            int temp1, temp2;
            int flag[max], m = 0;
            cout << "从" << amg.vexs[3 - 1] << "到" << amg.vexs[end - 1] << "最短路径为:" ;
            while (temp!= -1)
            {
                flag[m++] = temp;
                temp1 = temp ;
                temp2 = Path[temp1];
                temp = temp2;
            }
            for (int i = m-1; i >= 0; i--)
            {
                cout <<amg.vexs[flag[i]] << "->";
            }
            cout << endl;
            cout << "最短路径值为:" << D[end - 1] <<"米"<< endl;
        }
        else if (f == 3)
        {
            backGround();
        }
        else if (f == 4)
        {
            cout << ">>>退出成功!" << endl;
            exit(0);
        }
    }
}

实验结果
在这里插入图片描述
在这里插入图片描述

posted @ 2022-10-08 01:20  昔痕  阅读(77)  评论(0编辑  收藏  举报