POJ-2253||ZOJ-1942【最小生成树】

POJ-2253||ZOJ-1942

Frogger
Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to visit her, but since the water is dirty and full of tourists’ sunscreen, he wants to avoid swimming and instead reach her by jumping.

Unfortunately Fiona’s stone is out of his jump range. Therefore Freddy considers to use other stones as intermediate stops and reach her by a sequence of several small jumps.

To execute a given sequence of jumps, a frog’s jump range obviously must be at least as long as the longest jump occuring in the sequence.

The frog distance (humans also call it minimax distance) between two stones therefore is defined as the minimum necessary jump range over all possible paths between the two stones.

You are given the coordinates of Freddy’s stone, Fiona’s stone and all other stones in the lake. Your job is to compute the frog distance between Freddy’s and Fiona’s stone.

Input

The input will contain one or more test cases. The first line of each test case will contain the number of stones n (2<=n<=200). The next n lines each contain two integers xi,yi (0 <= xi,yi <= 1000) representing the coordinates of stone #i. Stone #1 is Freddy’s stone, stone #2 is Fiona’s stone, the other n-2 stones are unoccupied. There’s a blank line following each test case. Input is terminated by a value of zero (0) for n.

Output

For each test case, print a line saying “Scenario #x” and a line saying “Frog Distance = y” where x is replaced by the test case number (they are numbered from 1) and y is replaced by the appropriate real number, printed to three decimals. Put a blank line after each test case, even after the last one.

Sample Input
2
0 0
3 4

3
17 4
19 4
18 5

0

Sample Output
Scenario #1
Frog Distance = 5.000

Scenario #2
Frog Distance = 1.414

题目链接:
http://poj.org/problem?id=2253
题意:
一只青蛙在一块石头上,它要去另一个石头上找她老婆,它与它老婆之间还有其他石头,青蛙可以跳到石头上中转,可以跳很多次,但是要求每次起跳的距离尽量短一些,求最长的一段距离是多大,(就比如你要去距离你十米的一个地方,你可以步子很大的跨过去,但是本题要求你可以步子很小的走很多步,求最大的步子是多大)。
我(弱鸡)想到了用最小生成树,有的大佬用了dijkstra。
手头刚好有一个Kruskal板子,之前写过一个求最小生成树中最长的路的题,以为和这个题一样,改了改板子过了样例就提交了,果不其然wa了,wa的莫名其妙,然后看了看数据范围,发现数组结构体都开小了,然后又觉得wa的理所当然,然后又提交,又wa的莫名其妙。
仔细考虑过后,越发的觉得自己头脑简单,完全不可能抗衡充满“心机”的算法题。还是自己太年轻。
本题的正解为:不一定要把全部的石子都走一遍(之前的想法),将两点之间的距离从小到大排好序后,往集合里面丢,一旦发现青蛙起点石头和他老婆的石头到了一个集合里面(find(0)==find(1))记录下此时丢入集合中的那条边的距离即可,return输出该值即可!

 #include<stdio.h>
 #include<math.h>
 #include<algorithm>
 using namespace std;
 int n,m;
 const int inf = 0x3f3f3f3f;
 const int N =350;
 const int M =50500;
 struct edge {
  int a, b;
  double v;
  friend bool operator<(const edge A,edge B) {
   return A.v<B.v;
  }
 } e[M];
 int fa[N];
 void init() {
  for(int i=0; i<=n; ++i)
   fa[i]=i;
 }
 int find(int x) {
  if(x==fa[x])return x;
  else {
   fa[x]=find(fa[x]);
   return fa[x];
  }
 }
 int unito(int x,int y) {
  int A=find(x);
  int B=find(y);
  if(A!=B) {
   fa[A]=B;
   return 1;
  }
  return 0;
 }
 struct node {
  int x,y;
 } zz[N];
 double sss(node a,node b) {
  return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
 }
 double Kruksl() {
  for(int i=1; i<=n; ++i) {
   scanf("%d %d",&zz[i].x,&zz[i].y);
  }
  int cut=1;
  for(int i=1; i<=n; ++i) {
   for(int j=i+1; j<=n; ++j) {
    double ans=sss(zz[i],zz[j]);
    e[cut].a=i;
    e[cut].b=j;
    e[cut++].v=ans;
   }
  }
  m=cut;
  sort(e,e+m);
  double sum=0;
  for(int i=0; i<m; ++i) {
   if(unito(e[i].a,e[i].b)) {
    if(e[i].v>sum){
     sum=e[i].v;
    }
   }
  }
  return sum;
 }
 int main() {
  int k=1;
  while(scanf("%d",&n)&&n) {
   init();
   double ans=Kruksl();
   printf("Scenario #%d\n",k++);
   printf("Frog Distance = %.3f\n\n",sqrt(ans));
  }
  return 0;
 }

年少不读书,竟然(不知天高地厚)打acm。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值