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))

  • 相关阅读:
    基于Linux和Postfix的邮件系统的web mail安装手册(转)
    CodeGear Delphi 2007 for Win32 专业版下载地址及安装、破解方法
    Windows XP下屏蔽Ctrl_Alt_Del键的方法
    Cisco IOS 基本命令集
    WINDOWS下进程详解
    PHP 5.0 的变化与PHP 6.0 展望
    常用开源控件
    Windows XP下屏蔽Ctrl_Alt_Del键的方法
    Delphi 2007企业版安装指南
    PHP 5.0 的变化与PHP 6.0 展望
  • 原文地址:https://www.cnblogs.com/lingfunny/p/12825857.html
Copyright © 2011-2022 走看看