• 最短路径算法


    常见问题:

    求小区最短路径、求地铁最短路径、求给出图线之间从一点到另外一点的最短距离、求解所有的最短路径等

    思路:

    (1)将所有的点转换成Graph;(2)套用Floyd算法或者Dijkstra算法求解出最短路径。

    算法实现:

    (1)Floyd算法:http://www.cnblogs.com/skywang12345/p/3711523.html

    // 邻接矩阵
    typedef struct _graph
    {
        char vexs[MAX];       // 顶点集合
        int vexnum;           // 顶点数
        int edgnum;           // 边数
        int matrix[MAX][MAX]; // 邻接矩阵
    }Graph, *PGraph;
    /*
     * floyd最短路径。
     * 即,统计图中各个顶点间的最短路径。
     *
     * 参数说明:
     *        G -- 图
     *     path -- 路径。path[i][j]=k表示,"顶点i"到"顶点j"的最短路径会经过顶点k。
     *     dist -- 长度数组。即,dist[i][j]=sum表示,"顶点i"到"顶点j"的最短路径的长度是sum。
     */
    void floyd(Graph G, int path[][MAX], int dist[][MAX])
    {
        int i,j,k;
        int tmp;
    
        // 初始化
        for (i = 0; i < G.vexnum; i++)
        {
            for (j = 0; j < G.vexnum; j++)
            {
                dist[i][j] = G.matrix[i][j];    // "顶点i"到"顶点j"的路径长度为"i到j的权值"。
                path[i][j] = j;                 // "顶点i"到"顶点j"的最短路径是经过顶点j。
            }
        }
    
        // 计算最短路径
        for (k = 0; k < G.vexnum; k++)
        {
            for (i = 0; i < G.vexnum; i++)
            {
                for (j = 0; j < G.vexnum; j++)
                {
                    // 如果经过下标为k顶点路径比原两点间路径更短,则更新dist[i][j]和path[i][j]
                    tmp = (dist[i][k]==INF || dist[k][j]==INF) ? INF : (dist[i][k] + dist[k][j]);
                    if (dist[i][j] > tmp)
                    {
                        // "i到j最短路径"对应的值设,为更小的一个(即经过k)
                        dist[i][j] = tmp;
                        // "i到j最短路径"对应的路径,经过k
                        path[i][j] = path[i][k];
                    }
                }
            }
        }
    
        // 打印floyd最短路径的结果
        printf("floyd: 
    ");
        for (i = 0; i < G.vexnum; i++)
        {
            for (j = 0; j < G.vexnum; j++)
                printf("%2d  ", dist[i][j]);
            printf("
    ");
        }
    }
    

    (2)Dijkstra算法实现:http://www.cnblogs.com/skywang12345/p/3711512.html

    // 邻接矩阵
    typedef struct _graph
    {
        char vexs[MAX];       // 顶点集合
        int vexnum;           // 顶点数
        int edgnum;           // 边数
        int matrix[MAX][MAX]; // 邻接矩阵
    }Graph, *PGraph;
    
    // 边的结构体
    typedef struct _EdgeData
    {
        char start; // 边的起点
        char end;   // 边的终点
        int weight; // 边的权重
    }EData;
    

      

    /*
     * Dijkstra最短路径。
     * 即,统计图(G)中"顶点vs"到其它各个顶点的最短路径。
     *
     * 参数说明:
     *        G -- 图
     *       vs -- 起始顶点(start vertex)。即计算"顶点vs"到其它顶点的最短路径。
     *     prev -- 前驱顶点数组。即,prev[i]的值是"顶点vs"到"顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。
     *     dist -- 长度数组。即,dist[i]是"顶点vs"到"顶点i"的最短路径的长度。
     */
    void dijkstra(Graph G, int vs, int prev[], int dist[])
    {
        int i,j,k;
        int min;
        int tmp;
        int flag[MAX];      // flag[i]=1表示"顶点vs"到"顶点i"的最短路径已成功获取。
    
        // 初始化
        for (i = 0; i < G.vexnum; i++)
        {
            flag[i] = 0;              // 顶点i的最短路径还没获取到。
            prev[i] = 0;              // 顶点i的前驱顶点为0。
            dist[i] = G.matrix[vs][i];// 顶点i的最短路径为"顶点vs"到"顶点i"的权。
        }
    
        // 对"顶点vs"自身进行初始化
        flag[vs] = 1;
        dist[vs] = 0;
    
        // 遍历G.vexnum-1次;每次找出一个顶点的最短路径。
        for (i = 1; i < G.vexnum; i++)
        {
            // 寻找当前最小的路径;
            // 即,在未获取最短路径的顶点中,找到离vs最近的顶点(k)。
            min = INF;
            for (j = 0; j < G.vexnum; j++)
            {
                if (flag[j]==0 && dist[j]<min)
                {
                    min = dist[j];
                    k = j;
                }
            }
            // 标记"顶点k"为已经获取到最短路径
            flag[k] = 1;
    
            // 修正当前最短路径和前驱顶点
            // 即,当已经"顶点k的最短路径"之后,更新"未获取最短路径的顶点的最短路径和前驱顶点"。
            for (j = 0; j < G.vexnum; j++)
            {
                tmp = (G.matrix[k][j]==INF ? INF : (min + G.matrix[k][j])); // 防止溢出
                if (flag[j] == 0 && (tmp  < dist[j]) )
                {
                    dist[j] = tmp;
                    prev[j] = k;
                }
            }
        }
    
        // 打印dijkstra最短路径的结果
        printf("dijkstra(%c): 
    ", G.vexs[vs]);
        for (i = 0; i < G.vexnum; i++)
            printf("  shortest(%c, %c)=%d
    ", G.vexs[vs], G.vexs[i], dist[i]);
    }
  • 相关阅读:
    【HDU3721】枚举+最长路
    满足要求的最长上升子序列(nlogn)
    Flask入门 表单Flask-wtf form原生 Bootstrap渲染(七)
    Flask入门之模板导入与块宏(六)
    Flask入门模板过滤器与测试器(五)
    Flask入门模板Jinja2语法与函数(四)
    Flask入门flask-script 蓝本 钩子函数(三)
    Flask入门request session cookie(二)
    Flask入门 flask结构 url_for 重定向(一)
    Django问卷调查项目思路流程
  • 原文地址:https://www.cnblogs.com/usec/p/7403618.html
Copyright © 2020-2023  润新知