码迷,mamicode.com
首页 > 编程语言 > 详细

《啊哈算法》——最短路径

时间:2016-05-02 13:03:08      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:

  虽然笔者在“算法-图论”的专栏中已经讨论过有关最短路径的问题,但是这里还是重新讨论一下,孔子也说过嘛,温故而知新。

  所谓最短路径问题,就是基于一个图G<V、E>,图的边集E是带权的,然后讨论寻求某条连通两个点的路径,使得这条路径是所有连通该路径中边权最小的。

 

  找到任意两点间的最短路径——Floyd-Warshall算法。

  这个算法是个本科念文学后来转计算机并于1978年荣获图灵奖的Robert W.Floyd和Stephen Warshall于1962同时独立开发出来的,因此为了纪念他们,该算法融合了两个人的名字。

  其实这个算法说来思路也非常简单,我们当前想要求得G中vi到vj的最短路径,最简单暴力的方法是找到vi到vj所有可走的路径,然后维护一个最小值即可。然而现在问题是如何找到这所有的路径?我们找一个中间变量k,vi->vj的路径可以分解成vi->vk 、vk->vj的路径,而将k遍历[i,j]便可枚举出所有情况,你可能会问那vi->vk还有很多路径呢,那岂不还要继续找?事实上,我们设置e[i][j]记录vi->vj的最短路径,而vi->vk、vk->vj则也是基于e[i][k]、e[k][j]的,这样我们其实是枚举了一系列相对最优的情况,然后找到这些相对最优解中的当前最优解的情况,这便是动态规划思想所体现的地方。

  本质上讲,该算法是枚举和动态规划的一个巧妙的结合。

 

#include<cstdio>
using namespace std;

int main()
{
     int e[10][10] , k , i , j , n , m , t1,t2,t3;
     int inf = 9999999;
     scanf("%d%d",&n,&m);

     for(i = 1;i<=n;i++)
          for(j = 1;j<=n;j++)
             if(i == j)  e[i][j] = 0;
             else        e[i][j] = inf;

    for(i = 1;i<=m;i++)
    {
        scanf("%d%d%d",&t1,&t2,&t3);
        e[t1][t2] = t3;
    }

       for(k=1;k<=n;k++)
          for(i=1;i<=n;i++)
             for(j=1;j<=n;j++)
                if(e[i][j] > e[i][k] + e[k][j]) //Floyd-Warshall算法的核心部分
                   e[i][j] = e[i][k] + e[k][j];


       for(i=1;i<=n;i++)
       {
              for(j = 1;j<=n;j++)
                  printf("%10d",e[i][j]);

              printf("\n");
       }
       return 0;

}

 

《啊哈算法》——最短路径

标签:

原文地址:http://www.cnblogs.com/rhythmic/p/5452083.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!