zoukankan      html  css  js  c++  java
  • 多源最短路径算法:Floyd算法

    前言

    由于本人太菜,这里不讨论Floyd的正确性。

    简介

    多源最短路径,解决的是求从图中任意两点之间的最短路径的问题。

    分析

    代码短小精悍,主要代码只有四行,直接放上:

    for(int k=1;k<=n;++k)
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=n;++j)
    			dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    

    接下来一步一步分析这个算法。
    其实这个算法并不难,首先要知道,dis[i][j]表示的是从点i到点j的最短路径的长度。
    仔细看这个语句:dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    其实,可以再将它放大,变成这样:

    if(dis[i][k]+dis[k][j]<dis[i][j])
        dis[i][j]=dis[i][k]+dis[k][j];
    

    这个意思就是说,如果从点i到点k的最短路径长度加上点k到点j的最短路径长度比原来点i到点j的最短路径长度短,就把原来i->j的最短路径更新。
    你可能会说:

    诶你这不是i->k->j和i->j作比较吗,如果i->a->b->j比i->k->j更短呢?

    这时候,就要回顾一下我们的dis数组的含义了。dis[i][j]只表示点i到点j的最短路径的长度,并不是i->j的路径的长度。也就是说,我们不关心是怎么从i走到j的(可能是i->a->b->j,也可能是i->c->j),但是我们只想知道从i到j最短需要走多长,其实这就是dp(动态规划)的想法了。
    你可能会说:

    如果到不了呢??那还怎么算?

    这就涉及到初始化的问题了。
    由于是最短路径问题,所以如果到不了,我们可以将dis[i][j]的值设为inf(无穷大)。
    如果能从节点i直接走到节点j(这里是直接走到,就是i,j有一条边相连),就可以把dis[i][j]设为这条边的权值。
    在重新回顾一下Floyd的三重循环:

    for(int k=1;k<=n;++k)
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=n;++j)
                        //...
    

    其实这个k,就是我们不断枚举的中转点。如果从i到j经过中转点k会更短,就可以更新。
    时间复杂度显而易见:(O(n^3))

  • 相关阅读:
    mysql,apache,php的关系
    简析 Tomcat 、Nginx 与 Apache 的区别
    Linux中涉及到环境变量的文件
    如何在Linux启动的时候执行一个命令
    sed的额外用法(网摘)
    shell脚本执行方式
    在rhel7上搭建centos7的yum源
    MYSQL三种安装方式--二进制包安装
    ssh连接不上排查方法总结
    MySQL启动很慢的原因
  • 原文地址:https://www.cnblogs.com/lingfunny/p/12825857.html
Copyright © 2011-2022 走看看