题目链接:http://poj.org/problem?id=2253
题目:
弗雷迪青蛙正坐在湖中央的一块石头上。 突然,他注意到正坐在另一块石头上的菲奥娜青蛙。 他打算去看望她,但由于水很脏,游客的防晒霜很多,他想避免游泳,而是通过跳跃来到她身边。
不幸的是,菲奥娜的石头超出了他的跳跃范围。 因此,弗雷迪考虑使用其他石头作为中间站点并通过一系列小跳跃到达她。
要执行给定的跳跃序列,青蛙的跳跃范围显然必须至少与序列中发生的最长跳跃一样长。
因此,两块宝石之间的青蛙距离(人类也称之为极小极大距离)被定义为两块宝石之间所有可能路径上的最小必要跳跃范围。您将获得Freddy石头,Fiona石头和湖中所有其他石头的坐标。 你的工作是计算弗雷迪和菲奥娜之间的青蛙距离(最小必要跳跃距离)。
输入:
输入将包含一个或多个测试用例。每个测试用例的第一行将包含结石数n(2 <= n <= 200)。接下来的n行每行包含两个整数xi,yi(0 <= xi,yi <= 1000),表示石头#i的坐标。石头#1是弗雷迪的石头,石头#2是菲奥娜的石头,其他的n-2石头是无人居住的。每个测试用例后面都有一个空白行。对于n,输入以零(0)的值终止。
输出:
对于每个测试用例,打印一行“Scenario #x”和一行“Frog Distance = y”,其中x由测试用例编号替换(编号从1开始),y由相应的实数替换,打印到三位小数。在每个测试用例之后放一个空行,即使在最后一个测试用例之后。
思路:说一下最小必要跳跃距离(也就是他们所说的最长路中的最短路),比如说我们要从1 -> 8,我们有两条路:1 -> 4 -> 6 -> 8 和 1 -> 4 -> 8。这两条路我们要过去,跳的距离就一定要大于等于路中最大两点的距离(不然就到不了8这个点),这个距离就叫必要跳跃距离,第一条路必要跳跃距离是3,第二条是4,题目让我们求的是最小的必要跳跃距离,所以是3。理解这个那这一题就很简单了,三种最短路算法任意一种都可以求解。
还要注意一点:事实上,printf中没有定义%lf,但是很多系统可能会接受它。要确保可移植性,就要坚持使用%f。
建议大家使用double类型时,用%lf输入,%f输出避免出错。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
typedef long long LL;
const int N = 1000;
const int INF = 0x3f3f3f3f;
double dis[N], G[N][N];
int n, s;
int Case = 1;
bool vis[N];
struct node{ double x,y;} edge[N];
double dist(node a,node b){
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));}
void dijkstra()
{
for(int i = 1; i <= n; i++)
dis[i] = G[1][i];
dis[1] = 0;
for(int i = 1; i <= n; i++)
{
int k = -1;
for(int j = 1; j <= n; j++)
{
if(!vis[j] && (k == -1 || dis[j] < dis[k]))
k = j;
}
if(k == -1) break;
vis[k] = true;
for(int j = 1; j <= n; j++)
{
if(!vis[j]) dis[j] = min(dis[j], max(dis[k],G[k][j]));
}
}
printf("Scenario #%d\nFrog Distance = %.3f\n\n",Case++,dis[2]);
}
void floyd()
{
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
G[i][j] = min(G[i][j], max(G[i][k],G[k][j]));
printf("Scenario #%d\nFrog Distance = %.3f\n\n",Case++,G[1][2]);
}
void spfa()
{
queue<int>que;
for(int i = 1; i <= n; i++)
dis[i] = INF;
dis[1] = 0;
vis[1] = true;
que.push(1);
while(!que.empty())
{
int now = que.front();
que.pop();
vis[now] = false;
for(int i = 1; i <= n; i++)
{
if(dis[i] > max(dis[now],G[now][i]))
{
dis[i] = max(dis[now],G[now][i]);
if(!vis[i])
{
vis[i] = true;
que.push(i);
}
}
}
}
printf("Scenario #%d\nFrog Distance = %.3f\n\n",Case++,dis[2]);
}
int main()
{
while(~scanf("%d", &n) && n)
{
memset(vis, false, sizeof(vis));
for(int i = 1; i <= n; i++)
scanf("%lf%lf",&edge[i].x,&edge[i].y);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
G[i][j] = dist(edge[i],edge[j]);
dijkstra();
//floyd();
//spfa();
}
return 0;
}