题目链接: vjudge
题意(认真看!)
从1节点到2节点所有线路中,每条线路由若干跳组成,其中距离最大的一条为这条线路的青蛙距离。求所有线路中青蛙距离的最小值。
输入
输入将包含一个或多个测试案例。每个测试案例的第一行将包含石头的数量n(2<=n<=200)。接下来的n行分别包含两个整数xi,yi (0 <= xi,yi <= 1000) ,代表石头#i的坐标。。每个测试案例后面都有一个空行。输入以n的值为零(0)结束。
输出
对于每个测试案例,打印一行 "场景#x "和一行 “青蛙距离=y”,其中x由测试案例编号代替(它们从1开始编号),y由适当的实数代替,打印到三位小数。在每个测试案例后放一行空白,甚至在最后一个测试案例后也放一行。
输入样例
2
0 0
3 4
3
17 4
19 4
18 5
0
输出样例
Scenario #1
Frog Distance = 5.000
Scenario #2
Frog Distance = 1.414
解题思路
这个题可以用迪杰斯特拉和最小生成树算法。
迪杰斯特拉算法
使用dis[i]
表示从1到i点所有路线的青蛙距离。采用迪杰斯特拉算法的遍历,我们每次选出未选择点中到1点青蛙距离最小的点。然后更新所有未选择的点经过该点到1点的青蛙距离。因为我们每次都选择了青蛙距离最小的点,最后生成的序列连接到2点时,就是所有线路中青蛙距离的最小值。
AC代码
迪杰斯特拉算法
#include <stdio.h>
#include <cstring>
#include <vector>
#include <limits>
#include <math.h>
using namespace std;
typedef struct
{
int x, y;
} point;
int n;
double dis[205];
bool vis[205];
vector<point> v;
double max(double a, double b)
{
if (a > b)
return a;
else
return b;
}
double getLength(double x1, double y1, double x2, double y2)
{
double len = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
return len;
}
void init()
{
for (int i = 1; i <= n; i++)
vis[i] = 0;
for (int i = 2; i <= n; i++) // 初始化各个石头到1号石头的直接距离
dis[i] = getLength(v[1].x, v[1].y, v[i].x, v[i].y);
}
void dijkstra()
{
if (vis[2] == true)
return;
vis[1] = true;
int k;
for (int i = 1; i <= n; i++)
{
k = -1;
for (int j = 1; j <= n; j++)
{
if (!vis[j] && (k == -1 || dis[j] < dis[k]))
{
k = j;
}
}
vis[k] = true;
for (int j = 1; j <= n; j++)
{
// 青蛙距离就是这么判断的
if (vis[j] == false)
{
double len = getLength(v[k].x, v[k].y, v[j].x, v[j].y);
if (dis[j] > max(len, dis[k]))
dis[j] = max(len, dis[k]);
}
}
}
}
int main()
{
int a, b, times = 0;
while (scanf("%d", &n) && n != 0)
{
times++;
v.clear();
point blank;
blank.x = 0;
blank.y = 0;
v.push_back(blank);
// input
for (int i = 0; i < n; i++)
{
point buf;
scanf("%d %d", &buf.x, &buf.y);
v.push_back(buf);
}
init();
dijkstra();
printf("Scenario #%d\n", times);
printf("Frog Distance = %.3lf\n\n", dis[2]);
}
return 0;
}