zoukankan      html  css  js  c++  java
  • 最短路模板

    Floyd算法:

    写得很好的博客:最短路径问题---Floyd算法详解

    算法的特点: 

      弗洛伊德算法是解决任意两点间的最短路径的一种算法,可以正确处理有向图无向图负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包。

    算法的思路:

      通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入两个矩阵,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离。矩阵P中的元素b[i][j],表示顶点i到顶点j经过了b[i][j]记录的值所表示的顶点。

      假设图G中顶点个数为N,则需要对矩阵D和矩阵P进行N次更新。初始时,矩阵D中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞,矩阵P的值为顶点b[i][j]的j的值。 接下来开始,对矩阵D进行N次更新。第1次更新时,如果”a[i][j]的距离” > “a[i][0]+a[0][j]”(a[i][0]+a[0][j]表示”i与j之间经过第1个顶点的距离”),则更新a[i][j]为”a[i][0]+a[0][j]”,更新b[i][j]=b[i][0]。 同理,第k次更新时,如果”a[i][j]的距离” > “a[i][k-1]+a[k-1][j]”,则更新a[i][j]为”a[i][k-1]+a[k-1][j]”,b[i][j]=b[i][k-1]。更新N次之后,操作完成!

      

      代码很短耶 一会都可以背下来了。时间复杂度为O(n^3)

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 const int INF = 0x3f3f3f;
     6 
     7 int ma[105][105], n, m;
     8 void floyd()
     9 {
    10     for(int k = 1; k <= n; k++)
    11         for(int i = 1; i <= n; i++)
    12             for(int j = 1; j <= n; j++)
    13                 ma[i][j] = min(ma[i][j],ma[i][k]+ma[k][j]);
    14 }
    15 int main()
    16 {
    17     while(cin >> n >> m && n && m){
    18         memset(ma,INF,sizeof(ma));
    19         for(int a,b,c,i = 0; i < m; i++){
    20             cin >> a >> b >> c;
    21             ma[a][b] = ma[b][a] = min(ma[a][b],c);
    22         }
    23         floyd();
    24         cout << ma[1][n] << endl;
    25     }
    26     return 0;
    27 }

    Dijkstra算法:

    写得很好的博客:Dijkstra 最短路算法

    Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的

    /*可以输入以下数据进行验证第一行两个整数 n m。n 表示顶点个数(顶点编号为 1~n),m 表示边的条数。接下来 m 行表示,每行有 3 个数 x y z。表示顶点 x 到顶点 y 边的权值为 z。
    6 9
    1 2 1
    1 3 12
    2 3 9
    2 4 3
    3 5 5
    4 3 4
    4 5 13
    4 6 15
    5 6 4
    运行结果是
    0 1 8 4 13 17
    时间复杂度:O(N^2)
    */
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int INF = 0x3f3f3f;
    
    int main()
    {
        int n, m;
        int e[10][10], dis[10], book[10];
        cin >> n >> m;
        //初始化
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                if(i == j) e[i][j] = 0;
                else e[i][j] = INF;
        //读边
        for(int a,b,c,i = 1; i <= m; i++){
            cin >> a >> b >> c;
            e[a][b] = c;
        }
        //dis初始化
        for(int i = 1; i <= n; i++) dis[i] = e[1][i];
        //book初始化
        for(int i = 1; i <= n; i++) book[i] = 0;
        book[1] = 1;   //从点1开
    
        //Dijkstra:
        int minn, u;
        for(int i = 1; i <= n-1; i++){
            //先找离1最近的点:
            minn = INF;
            for(int j = 1; j <= n; j++)
                if(book[j] == 0 && dis[j] < minn){
                    minn = dis[j];
                    u = j;
            }
            book[u] = 1;
            for(int v = 1; v <= n; v++)
                if(e[u][v] < INF){
                    if(dis[v] > dis[u]+e[u][v])
                        dis[v] = dis[u]+e[u][v];
            }
        }
    
        //输出点1到每条边的距离:
        for(int i = 1; i <= n; i++)
            cout << dis[i] << " ";
        return 0;
    }

    我jio得  大佬们都已经写得很好啦。还有补充的,以后有了再加。

    还有几个其他的最短路算法

    未完待续.......

  • 相关阅读:
    《自我介绍》
    《结对-结对编项目作业名称-开发环境搭建过程》
    提取图形中指定颜色的所有像素_opencv/c++
    图形锐化_opencv/C++
    Opencv2.4.13 与Visual Studio2013 环境搭建配置
    C++基础——C面向过程与C++面向对象编程01_圆面积求解
    2017年2月26日
    基于GDAL的遥感影像显示(C#版)
    GDAL C# 开发环境配置
    shp文件的读取
  • 原文地址:https://www.cnblogs.com/JiaaaaKe/p/9559848.html
Copyright © 2011-2022 走看看