POJ - 2253 最短路变式 求路径中的最小的最大边 采用未优化的迪杰斯特拉 这题瞎改一波代码居然一波AC了 真神奇

题目

在这里插入图片描述

题解思路

首先用邻接矩阵存放每个点直接的距离,
两块石头之间的青蛙距离被定义为两块石头之间所有可能路径上的最小必要跳跃距离,某条路径的必要跳跃距离即这条路径中单次跳跃的最远跳跃距离。
算两个点之间路径中的最小的最大边
核心代码 就在这里 其他和迪杰斯特拉模板 都 差不多

 if ( mp[t1][j] < 999999 )
          if ( dis[j] >   max (dis[t1],mp [t1][j] ) )
              {
              //      printf("dis[%d]=%.3f\n",j,dis[j]);
                        dis[ j ] =  max (dis[t1],mp [t1][j] ) ;
               //     printf("dis[%d]=%.3f\n",j,dis[j]);
              }

我理解为 在所有可行的路中,保证此刻路径长度最小,不断松弛取最大的边 ,这样取出来的,就是答案。
if ( mp[t1][j] < 999999 ) 确保了这条路是否可行。而 dis[j] > max (dis[t1],mp [t1][j] ) 确保了这是一条 可以松弛的边,
而迪杰斯特拉 算法中 的思想是 每次从离源点最近 的 进行松弛 ,这样 我们就能保证这是当前路径长度情况最小的 ,把松弛最短距离的代码改成,求最大边 即可 。

AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
double  mp [1005][1005];
int dx[1005];
int dy[1005];
double  dis [1005];
bool vis[1005];
double ju (int x1,int y1,int x2,int y2)
{
    return  sqrt(1.0*(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)*1.0);
}
int main ()
{
    int n,sum  = 1;
    while(cin>>n&&n)
    {
        if (sum != 1)
            printf("\n");
        memset( mp , 999999 ,sizeof(mp) );
        memset( vis , 0 ,sizeof(vis) );
        for (int i = 1 ;i <= n ; i++ )
        {
            int a,b;
            cin>>a>>b;
            dx [i] = a;
            dy [i] = b;
        }
        for (int i = 1 ;i <= n ; i ++ )
        {
             for (int k = 1 ; k <= n ; k++)
             {
                 mp [ i ][ k ] =  ju (dx[i],dy[i],dx[k],dy[k]);
             }
        }
        for (int i = 1 ; i <= n ; i++)
          {
               dis [i] = mp[ 1 ] [ i ];
            //   printf("dis[%d]=%.3f\n", i ,dis[i]);
          }
        vis[1] = 1;
        for (int i = 1 ;i <= n ; i++ )
        {
            int t = 999999,t1 = i;
            for (int k = 1 ; k <= n ; k++ )
            {

                if (vis [k] == 0 && dis[k] < t  )
                {
                    t = dis [k];
                    t1 = k;
                }
            }
            vis[t1] = 1;
           //    printf("dis[%d]=%.3f\n", t1 ,dis[t1]);
            for (int j = 1 ; j <= n ; j++ )
            {
                if ( mp[t1][j] < 999999 )
                    if ( dis[j] >   max (dis[t1],mp [t1][j] ) )
                    {
                  //      printf("dis[%d]=%.3f\n",j,dis[j]);
                        dis[ j ] =  max (dis[t1],mp [t1][j] ) ;
                   //     printf("dis[%d]=%.3f\n",j,dis[j]);
                    }
            }
        }

        printf("Scenario #%d\n",sum);
        sum++;
        printf("Frog Distance = %.3f\n",dis[2] );
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值