最短路问题(Floyd解决)--殊途同归

简介: 最短路问题(Floyd解决)--殊途同归

题目:在小米之城,有 n个小镇(从 1 开始编号),这些小镇通过 m条双向火车铁轨相连,当然某些小镇之间也有公路相连。为了保证每两个小镇之间的人可以方便地互访,市长米小兔就在那些没有铁轨连接的小镇间建造了公路。在两个直接通过公路或铁路相连的小镇之间移动,需要花费 1 小时。火车只能走铁路,汽车只能走公路。


现在有一辆火车和一辆汽车同时从小镇 1 出发,各自前往小镇 n。但是,他们中途不能同时停在同一个小镇(但是可以同时停在小镇 n)。


现在请你来为火车和汽车分别设计一条线路,使火车和汽车尽可能快地到达小镇 n(即要求他们中最后到达小镇 n的时间最短)。


所有的公路或铁路可以被多次使用,求当火车、汽车中各自到达小镇时间最短时,总用时最小的一个。(火车和汽车可以同时到达小镇 n,也可以先后到达。)


这个题目我读了半个小时也没有读懂…(自我嫌弃.jpg)

输入:单组测试数据。


首先有 2 个整数 n和 m(2≤ n≤400,0≤m≤n*(n-1)/2)分别表示小镇的数目和铁轨的数目;


接下来的 m对数字,每对由两个整数 u 和 v 构成,表示小镇 u 和小镇 v之间有一条铁路。(1≤u,v≤n,u!=v)。


输入中保证两个小镇之间最多有一条铁路直接相连。

输出:输出一个整数,表示答案,如果没有合法的路线规划,输出 -1.


23.png

代码如下:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f  //十六进制无穷大
using namespace std;
const int maxn=450;  
int mp[maxn][maxn]; //存图的二维数组定义在外部
int vis[maxn];
int dis[maxn];
int ans,sum,n,m;
void dij(int v)
{
  int _min,pos=-1;
  memset(vis,0,sizeof(vis));
  for(int i=1;i<=n;i++)
  {
    dis[i]=mp[v][i];
  }
  dis[v]=0;
  vis[v]=1;
  for(int i=1;i<n;i++)
  {
    _min=inf;    //让最小值等于无穷小就可以当最小值比别的值大的时候进行替换
    for(int j=1;j<=n;j++)
    {
      if(!vis[j]&&dis[j]<_min)    //判断:vis那个值非零,并且dis那个值小于最小值
      {
        _min=dis[j];
        pos=j;
      }
    }
    vis[pos]=1;
    for(int j=1;j<=n;j++)
    {
      if(!vis[j]&&dis[j]>dis[pos]+mp[pos][j])
      {
        dis[j]=dis[pos]+mp[pos][j];
      }
    }
  }
}
int main()
{
    scanf("%d%d",&n,&m);
    ans=sum=0;
    if(m==0)
    {
      printf("-1\n");
      return 0;
  }
  else
  {
    memset(mp,inf,sizeof(mp));
    memset(dis,inf,sizeof(dis));
    for(int i=0;i<m;i++)
    {
      int u,v;
      scanf("%d%d",&u,&v);
      mp[u][v]=mp[v][u]=1;
    } 
    dij(1);
    ans=dis[n];
    if(ans==inf||m==(n*(n-1))/2)
    {
      printf("-1\n");
      return 0;
    }
    else
    {
      for(int i=1;i<=n;i++)
      {
        for(int j=1;j<=n;j++)
        {
          if(mp[i][j]==1)
          {
            mp[i][j]=inf;
          }
          else
          {
            mp[i][j]=1;
          }
        }
      }
      dij(1);
      sum=dis[n];
    }
    printf("%d\n",max(sum,ans));
  }
    return 0;
}

总结的来说,做最短路的题要注意这个方面:

1.尽量把初始化语句和算法语句封装成函数;

2.图的顶点和边的个数,以及存图的二维数组,定义在main函数外部;

3.注意是有向图还是无向图;

4.图的点是从1开始计算还是0开始计算;

5.每个测试样例一定要初始化存图的数组。

6.判断最短路存在与否的条件是arr[i][j] 是否等于INF。


Floyd的核心算法:
void floyd()
{
    for(int k = 0 ; k < N ; k++)
        for(int i = 0 ; i < N ; i++)
            for(int j = 0 ; j < N ; j++)
            {
                if(arr[i][k] < INF && arr[k][j] < INF && arr[i][j] > arr[i][k] + arr[k][j])
                    arr[i][j] = arr[i][k] + arr[k][j];
            }
}


相关文章
|
算法 Android开发 索引
LeetCode 周赛上分之旅 #44 同余前缀和问题与经典倍增 LCA 算法
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
82 0
|
算法 测试技术 Android开发
LeetCode 周赛上分之旅 #45 精妙的 O(lgn) 扫描算法与树上 DP 问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
74 2
LeetCode 周赛上分之旅 #45 精妙的 O(lgn) 扫描算法与树上 DP 问题
算法学习--最短路问题
算法学习--最短路问题
|
搜索推荐 算法
离散数学_九章:关系 —— 拓扑排序
离散数学_九章:关系 —— 拓扑排序
148 0
|
机器学习/深度学习 安全
洛谷P2245 星际导航(kruskal重构树)
洛谷P2245 星际导航(kruskal重构树)
118 0
|
算法 JavaScript 前端开发
会一会改变世界的图算法——Dijkstra(狄克斯特拉)算法
狄克斯特拉算法是非常著名的算法,是改变世界的十大算法之一,用于解决【赋权】【有向无环图】的【单源最短路径】问题。
|
机器学习/深度学习 算法
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
|
存储 算法
一文足矣——动态规划经典之Floyd(弗洛伊德)算法
一文足矣——动态规划经典之Floyd(弗洛伊德)算法
250 0
一文足矣——动态规划经典之Floyd(弗洛伊德)算法
|
算法 定位技术 Perl