校园图最短路径查找

校园图最短路径查找

 

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

#define MAXVEX 15   //顶点数,应由用户定义
#define NUMBER 23   //边数,应由用户定义
#define INF 9999999 //定义一个无穷大数

struct Vexs
{
    string name; //地点名称
};

struct Graph
{
    Vexs vexs[MAXVEX];         //顶点表(以中文信息存储)结构体数组
    int arc[MAXVEX][MAXVEX];   //邻接矩阵,可看作边
    int numVertexes, numEdges; //图中当前的顶点数和边数
};

//事先把地图信息存储起来
//地点名称
string vexname[15] = {
    "大门",
    "教学区1",
    "图书馆",
    "结构楼",
    "煤炭楼",
    "教学区2",
    "体育馆",
    "田径场",
    "网球场",
    "男生宿舍楼",
    "女生宿舍楼",
    "学生超市",
    "骊秀苑",
    "榴馨苑",
    "综合楼"};
//初始化地点名称1
string loadingOne[23] = {
    "大门",
    "教学区1",
    "煤炭楼",
    "煤炭楼",
    "教学区2",
    "教学区2",
    "教学区1",
    "教学区1",
    "教学区1",
    "图书馆",
    "图书馆",
    "图书馆",
    "综合楼",
    "综合楼",
    "综合楼",
    "榴馨苑",
    "榴馨苑",
    "骊秀苑",
    "骊秀苑",
    "骊秀苑",
    "男生宿舍楼",
    "网球场",
    "网球场",
};
//初始化地点名称2
string loadingTwo[23] = {
    "教学区1",
    "煤炭楼",
    "结构楼",
    "教学区2",
    "田径场",
    "体育馆",
    "体育馆",
    "图书馆",
    "女生宿舍楼",
    "体育馆",
    "综合楼",
    "女生宿舍楼",
    "体育馆",
    "骊秀苑",
    "榴馨苑",
    "学生超市",
    "骊秀苑",
    "体育馆",
    "学生超市",
    "男生宿舍楼",
    "网球场",
    "田径场",
    "体育馆",
};
//初始化地点路程
int loadingNum[23] = {
    212,
    200,
    20,
    150,
    220,
    130,
    230,
    160,
    180,
    200,
    120,
    110,
    180,
    80,
    170,
    45,
    80,
    152,
    151,
    200,
    180,
    160,
    200,
};

//定位
int locates(Graph *g, string ch)
{
    int i = 0;
    for (i = 0; i < g->numVertexes; i++)
    {
        if (g->vexs[i].name == ch)
        {
            break;
        }
    }
    if (i >= g->numVertexes)
    {
        return -1;
    }
    return i;
}

//建立一个无向网图的邻接矩阵表示
void createGraph(Graph *g)
{

    int i, j, k, w;
    //初始化顶点数和边数
    g->numVertexes = MAXVEX; //15个顶点
    g->numEdges = NUMBER;    //22条边

    //初始化广东理工学院地点名称、代号、简介
    for (i = 0; i < g->numVertexes; i++)
    {
        g->vexs[i].name = vexname[i];
    }

    //邻接矩阵初始化为每个单元为INF
    for (i = 0; i < g->numVertexes; i++)
    {
        for (j = 0; j < g->numVertexes; j++)
        {
            g->arc[i][j] = INF;
        }
    }
    cout << endl;

    //初始化地图的各地点权值矩阵
    for (k = 0; k < g->numEdges; k++)
    {
        string p, q;
        p = loadingOne[k];
        q = loadingTwo[k];
        w = loadingNum[k];
        int m = -1;
        int n = -1;
        m = locates(g, p); //若m等于-1,说明在矩阵中并没有定位到
        n = locates(g, q);
        if (m == -1 || n == -1)
        {
            cout << "there is no vertex."<<loadingOne[k]<<" "<<loadingTwo[k]  << endl; //显示输入有错信息
            exit(-1);
        }
        g->arc[m][n] = w;
        g->arc[n][m] = w; //因为是无向图,矩阵对称
    }
}


//输出任一两点间的最短路径与长度
void Dispath(int dist[], int path[], int vv, int ee, Graph g) //输出从源点v出发的所有最短路径
{
    int i, j, k;
    int d; //存放一条最短路径(逆向)及其顶点个数
    string apath[MAXVEX];
    for (i = 0; i < g.numVertexes; i++) //n为顶点个数,循环n次,输出源点到其余各个顶点的最短路径和路径长度
    {
        if (i == ee)
        {
            cout << "从" << g.vexs[vv].name << "到" << g.vexs[ee].name << "的路径长度为:" << dist[i] << "\t路径为:";

            d = 0;
            apath[d] = g.vexs[i].name; //源点到i的最短路径上的终点为i,终点i存放在apath[0]
            k = path[i];               //源点到i的最短路径上,顶点i的前一个顶点为k
            if (k == -1)
                //没有路径的情况
                cout << "无路径\n";
            else //存在源点到i的最短路径时输出该路径
            {
                while (k != vv) //当k值等于源点编号时,循环结束
                {
                    d++;
                    apath[d] = g.vexs[k].name; //将源点v到i的最短路径上所经过的顶点编号,逆序存放在apath[d]
                    k = path[k];
                }
                d++;
                apath[d] = g.vexs[vv].name; //存储源点v到i的最短路径上的起点v

                cout << apath[d];            //先输出起点
                for (j = d - 1; j >= 0; j--) //再输出其他顶点
                {
                    cout << "->" << apath[j];
                }
            }
        }
    }
}
//求任一两地点之间的最短路径和长度
void shortestPath(Graph g, int v, int e)

{
    int vv = v;
    int ee = e;
    int dist[MAXVEX], path[MAXVEX];
    int F[MAXVEX];
    int mindis, i, j, u;
    for (i = 0; i < g.numVertexes; i++)
    {
        dist[i] = g.arc[v][i]; //距离初始化
        F[i] = 0;              //F[]置空
        if (g.arc[v][i] < INF) //路径初始化 等价于如果有边
            path[i] = v;       //顶点v到i有边时
        else
            path[i] = -1; //顶点v到i没边时
    }
    F[v] = 1;                           //源点v放入S中
    for (i = 0; i < g.numVertexes; i++) //循环n次
    {
        mindis = INF;
        for (j = 0; j < g.numVertexes; j++)
            if (F[j] == 0 && dist[j] < mindis)
            {
                u = j;
                mindis = dist[j];
            }
        //优化思路:如果F[ee]=1,那么程序就可以结束了
        F[u] = 1;                           //顶点u加入S中
        for (j = 0; j < g.numVertexes; j++) //修改不在s中的顶点的距离
            if (F[j] == 0)
                if (dist[u] + g.arc[u][j] < dist[j])
                {
                    dist[j] = dist[u] + g.arc[u][j];
                    path[j] = u;
                }
    }
    Dispath(dist, path, vv, ee, g); //输出最短路径
    cout << endl;
}

//功能实现
int function()
{
    Graph g;
    Graph *ptr = &g;
    createGraph(ptr); //邻接矩阵创建图
    int v, e;
    char chose;
    string str, start, end;
    while (true)
    {
        cout << "查询西科大任两个地点间的最短路径和长度" << endl;
        cout<<"以下为系统收录地点名称:"<<endl;
        for(int i=0;i<MAXVEX;i++)
        {
            cout<<vexname[i];
            cout<<"  ";
        }
        cout<<endl;

        cout << "请输入任意两地的名称,名称之间用空格隔开,以回车结束:" << endl;
        cin >> start >> end;
        v = locates(ptr, start);
        e = locates(ptr, end);
            if (v == -1 || e == -1)
            {
                cout << "查询地点发生错误,请重新操作!!!!" << endl;
            }
            else
            {
                shortestPath(g, v, e);
            }
            cout << endl;


        
        cin.ignore(100, '\n');
    }
}
int main(void)
{
    function();
    system("pause");
}

上一篇:python单元测试cvs/xml使用allure展示测试报告


下一篇:PTA 6-7 十进制转换二进制 (15 分) 简单的递归