• 最短路径


     有向图找最短路径

    /*最短路径*/
    
    #include <iostream>
    using namespace std;
    
    #define MaxInt 32767                                        //表示极大值,即∞
    #define MVNum 100                                           //最大顶点数
    typedef char VerTexType;                                      //假设顶点的数据类型为字符型 
    typedef int ArcType;                                          //假设边的权值类型为整型
    
    
    typedef struct 
    {
        VerTexType vexs[MVNum];                                    //顶点表 
        ArcType arcs[MVNum][MVNum];                              //邻接矩阵 
        int vexnum, arcnum;                                        //图的当前点数和边数 
    }AMGraph;
    
    int LocateVex(AMGraph G, VerTexType v) 
    {
        for (int i = 0; i < G.vexnum; ++i)
            if (G.vexs[i] == v)
                return i;
        return -1;
    }
    
    void CreateUDN(AMGraph &G)
    {
        int i, j, k;
        cout << "请输入总顶点数,总边数,以空格隔开:";
        cin >> G.vexnum >> G.arcnum;                            
        cout << endl;
    
        cout << "输入点的名称:" << endl;
    
        for (i = 0; i < G.vexnum; ++i) {
            cin >> G.vexs[i];                                    
        }
        cout << endl;
        for (i = 0; i < G.vexnum; ++i)                         
            for (j = 0; j < G.vexnum; ++j)
                G.arcs[i][j] = MaxInt;
        cout << "输入边依附的顶点及权值,如a b 7" << endl;
        for (k = 0; k < G.arcnum; ++k) {                            
            VerTexType v1, v2;
            ArcType w;
            cout << "请输入第" << (k + 1) << "条边依附的顶点及权值:";
            cin >> v1 >> v2 >> w;                                
            i = LocateVex(G, v1);  j = LocateVex(G, v2);        
            G.arcs[i][j] = w;                        
        }
    }
    
    /***************迪杰特斯拉算法****************/
    
    int *D = new int[MVNum];                                        //用于记录最短路的长度
    bool *S = new bool[MVNum];                                      //标记顶点是否进入S集合
    int *Path = new int[MVNum];                                    //用于记录最短路顶点的前驱
    
    
    void ShortestPath_DIJ(AMGraph G, int v0) {
        //用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径 
        int v, i, w, min;
        int n = G.vexnum;                                        //n为G中顶点的个数 
    
        for (v = 0; v < n; ++v) {                                 //n个顶点依次初始化 
            S[v] = false;                                          //S初始为空集 
            D[v] = G.arcs[v0][v];                               //将v0到各个终点的最短路径长度初始化为弧上的权值 
            if (D[v] < MaxInt)  Path[v] = v0;                      //如果v0和v之间有弧,则将v的前驱置为v0 
            else Path[v] = -1;                                   //如果v0和v之间无弧,则将v的前驱置为-1 
        }//for 
    
        S[v0] = true;                                                //将v0加入S 
        D[v0] = 0;                                                  //源点到源点的距离为0 
    
        for (i = 1; i < n; ++i) {                                    //对其余n-1个顶点,依次进行计算 
            min = MaxInt;
            for (w = 0; w < n; ++w)
                if (!S[w] && D[w] < min) 
                {                        //选择一条当前的最短路径,终点为v 
                    v = w;
                    min = D[w];
                }            
            S[v] = true;                                           //将v加入S 
            for (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 DisplayPath_DIJ(AMGraph G, int begin, int temp) 
    {
        if (Path[temp] != -1)
        {
            DisplayPath_DIJ(G, begin, Path[temp]);
            cout << G.vexs[Path[temp]] << "-->";
        }
    }
    
    /***************佛洛伊德算法*************/
    
    
    int Path_F[MVNum][MVNum];                        //最短路径上顶点vj的前一顶点的序号
    int D_F[MVNum][MVNum];                        //记录顶点vi和vj之间的最短路径长度
    
    void ShortestPath_Floyed(AMGraph G) {
        //用Floyd算法求有向网G中各对顶点i和j之间的最短路径 
        int i, j, k;
        for (i = 0; i < G.vexnum; ++i)                  //各对结点之间初始已知路径及距离 
            for (j = 0; j < G.vexnum; ++j) {
                D_F[i][j] = G.arcs[i][j];
                if (D_F[i][j] < MaxInt && i != j)  Path_F[i][j] = i;      //如果i和j之间有弧,则将j的前驱置为i 
                else Path_F[i][j] = -1;                      //如果i和j之间无弧,则将j的前驱置为-1 
            }
        for (k = 0; k < G.vexnum; ++k)
            for (i = 0; i < G.vexnum; ++i)
                for (j = 0; j < G.vexnum; ++j)
                    if (D_F[i][k] + D_F[k][j] < D_F[i][j]) {           //从i经k到j的一条路径更短 
                        D_F[i][j] = D_F[i][k] + D_F[k][j];            //更新D[i][j] 
                        Path_F[i][j] = Path_F[k][j];                   //更改j的前驱为k 
                    }
    }
    
    void DisplayPath_Floyed(AMGraph G, int begin, int temp)
    {
        if (Path_F[begin][temp] != -1) {
            DisplayPath_Floyed(G, begin, Path_F[begin][temp]);
            cout << G.vexs[Path_F[begin][temp]] << "-->";
        }
    }
    
    void main()
    {
        AMGraph G;
        int i, j, num_start, num_destination;
        VerTexType start, destination;
        CreateUDN(G);
        cout << endl;
        cout << "有向网G创建完成: "<< endl;
    
        for (i = 0; i < G.vexnum; ++i) {
            for (j = 0; j < G.vexnum; ++j) {
                if (j != G.vexnum - 1) {
                    if (G.arcs[i][j] != MaxInt)
                        cout << G.arcs[i][j] << "	";
                    else
                        cout << "" << "	";
                }
                else {
                    if (G.arcs[i][j] != MaxInt)
                        cout << G.arcs[i][j] << endl;
                    else
                        cout << "" << endl;
                }
            }
        }
        cout << "
    迪杰特斯拉算法:"<<endl;
    
        cout << "
    请依次输入起始点、终点名称:";
        cin >> start >> destination;
        num_start = LocateVex(G, start);
        num_destination = LocateVex(G, destination);
        ShortestPath_DIJ(G, num_start);
        cout << endl << "最短路径为:";
        DisplayPath_DIJ(G, num_start, num_destination);
        cout << G.vexs[num_destination] << endl;
        cout << "最短路径的长度为:" << D[num_destination] << endl;
        /****************************************/
    
        cout << "
    佛洛伊德算法:" << endl;
    
        ShortestPath_Floyed(G);
        cout << "
    请依次输入路径的起点与终点的名称:";
        cin >> start >> destination;
        num_start = LocateVex(G, start);
        num_destination = LocateVex(G, destination);
        cout << endl << "最短路径为:";
        DisplayPath_Floyed(G, num_start, num_destination);
        cout << G.vexs[num_destination] << endl;
        cout << "最短路径的长度为:" << D_F[num_start][num_destination] << endl;
        cout << endl;
    }

     运行结果:

  • 相关阅读:
    Git SVN 版本控制 简介 总结 MD
    shape selector 背景 圆形 矩形 圆环 [MD]
    eclipse library jar包 使用总结 MD
    Visitor 访问者模式 [MD]
    BlazeMeter+Jmeter 搭建接口测试框架
    nGrinder 简易使用教程
    65个面试常见问题技巧回答(绝对实用)
    [面试技巧]16个经典面试问题回答思路
    质量模型测试电梯
    linux apache服务器优化建议整理(很实用)
  • 原文地址:https://www.cnblogs.com/cjwen/p/11177692.html
Copyright © 2020-2023  润新知