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