zoukankan      html  css  js  c++  java
  • Floyd算法(弗洛伊德算法) 百度百科

    核心代码

    for(int k=1; k<=NODE; ++k)//对于每一个中转点
        for(int i=0; i<=NODE; ++i)//枚举源点
            for(int j=0; j<=NODE; ++j)//枚举终点
                if(distmap[i][j]>distmap[i][k]+distmap[k][j])//不满足三角不等式
                {
                    distmap[i][j]=distmap[i][k]+distmap[k][j];//更新
                    path[i][j]=k;//记录路径
                }




    状态转移方程

    状态转移方程如下: map[i,j]:=min{map[i,k]+map[k,j],map[i,j]};
    map[i,j]表示i到j的最短距离,K是穷举i,j的断点,map[n,n]初值应该为0,或者按照题目意思来做。
    当然,如果这条路没有通的话,还必须特殊处理,比如没有map[i,k]这条路。

    时间复杂度与空间复杂度

    编辑
    时间复杂度:O(n^3);

    优缺点分析

    编辑
    Floyd算法适用于APSP(All Pairs Shortest Paths,多源最短路径),是一种动态规划算法,稠密图效果最佳,边权可正可负。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高于执行|V|次Dijkstra算法,也要高于执行V次SPFA算法
    优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单。
    缺点:时间复杂度比较高,不适合计算大量数据。

    算法描述

    编辑
    a) 初始化:D[u,v]=A[u,v]
    b) For k:=1 to n
    For i:=1 to n
    For j:=1 to n
    If D[i,j]>D[i,k]+D[k,j] Then
    D[i,j]:=D[i,k]+D[k,j];
    c) 算法结束:D即为所有点对的最短路径矩阵

    参考代码

    编辑

    C语言

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #include<stdio.h>
    #include<stdlib.h>
    #define max 1000000000
    int d[1000][1000],path[1000][1000];
    int main()
    {
    int i,j,k,m,n;
    int x,y,z;
    scanf("%d%d",&n,&m);
     
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++){
        d[i][j]=max;
        path[i][j]=j;
    }
     
    for(i=1;i<=m;i++)
    {
    scanf("%d%d%d",&x,&y,&z);
    d[x][y]=z;
    d[y][x]=z;
    }
     
    for(k=1;k<=n;k++)
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    {
    if(d[i][k]+d[k][j]<d[i][j]){
        d[i][j]=d[i][k]+d[k][j];
        path[i][j]=path[i][k];
        }
    }
     
    for(i=1;i<=n;i++)
    for(j=1;j<=i;j++)
      if (i!=j) printf("%d->%d:%d ",i,j,d[i][j]);
     
    int f,en;
    scanf("%d%d",&f,&en);
    while (f!=en){
        printf("%d->",f);
        f=path[f][en];
    }
    printf("%d ",en);
     
    return 0;
    }

    C++语言

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    #include<iostream>
    #include<vector>
    using namespace std;
    const int &INF=100000000;
    void floyd(vector<vector<int> > &distmap,//可被更新的邻接矩阵,更新后不能确定原有边
               vector<vector<int> > &path)//路径上到达该点的中转点
    //福利:这个函数没有用除INF外的任何全局量,可以直接复制!
    {
        const int &NODE=distmap.size();//用邻接矩阵的大小传递顶点个数,减少参数传递
        path.assign(NODE,vector<int>(NODE,-1));//初始化路径数组 
        for(int k=1; k!=NODE; ++k)//对于每一个中转点
            for(int i=0; i!=NODE; ++i)//枚举源点
                for(int j=0; j!=NODE; ++j)//枚举终点
                    if(distmap[i][j]>distmap[i][k]+distmap[k][j])//不满足三角不等式
                    {
                        distmap[i][j]=distmap[i][k]+distmap[k][j];//更新
                        path[i][j]=k;//记录路径
                    }
    }
    void print(const int &beg,const int &end,
               const vector<vector<int> > &path)//传引用,避免拷贝,不占用内存空间
               //也可以用栈结构先进后出的特性来代替函数递归 
    {
        if(path[beg][end]>=0)
        {
            print(beg,path[beg][end],path);
            print(path[beg][end],end,path);
        }
        else cout<<"->"<<end;
    }
    int main()
    {
        int n_num,e_num,beg,end;//含义见下
        cout<<"(不处理负权回路)输入点数、边数:";
        cin>>n_num>>e_num;
        vector<vector<int> > path,
              distmap(n_num,vector<int>(n_num,INF));//默认初始化邻接矩阵
        for(int i=0,p,q; i!=e_num; ++i)
        {
            cout<<"输入第"<<i+1<<"条边的起点、终点、长度(100000000代表无穷大,不联通):";
            cin>>p>>q;
            cin>>distmap[p][q];
        }
        floyd(distmap,path);
        cout<<"计算完毕,可以开始查询,请输入出发点和终点:";
        cin>>beg>>end;
        cout<<"最短距离为"<<distmap[beg][end]<<",打印路径:"<<beg;
        print(beg,end,path);
    }

  • 相关阅读:
    大项目之网上书城(五)——主页(End)
    # 大项目之网上书城(四)——主页(下中)
    大项目之网上书城(三)——主页(中)
    大项目之网上书城(二)——主页(上)
    大项目之网上书城(一)——注册页面
    Mycat
    centos7 bash: netstat: 未找到命令
    docker 推送镜像到Harbor错误修改
    Jenkins插件下载镜像加速
    docker镜像加速器
  • 原文地址:https://www.cnblogs.com/coded-ream/p/7208025.html
Copyright © 2011-2022 走看看