POJ2253 Frogger【並查集+貪心】
Frogger
Time Limit: 1000MS | Memory Limit: 65536K |
Total Submissions: 61596 | Accepted: 19242 |
Description
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
Source
問題描述:青蛙Freddy和Fiona在一條河中,河中有n個石頭,Freddy在1號石頭上,Fiona在2號石頭上,Freddy想去見Fiona,由於河水很髒,Freddy只能通過跳躍到達目的地。從石頭i(x1,y1)到石頭j(x2,y2)的距離為i和j的二維笛卡爾座標距離。對於一種可行的路線,取跳躍距離最大的一步,可能有多種可行路線,最終答案是取各個可行路線中最大一步的最小值。
解題思路:並查集+貪心,求出n個點之間的相互距離,按距離從小到大排序,然後從小到大加邊,直到石頭1和石頭2相連,那麼最後新增的一條邊一定是所求值
AC的C++程式:
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=205;
int pre[N];
//初始化函式 :使各個結點是自己的父節點
void init(int n)
{
for(int i=1;i<=n;i++)
pre[i]=i;
}
int find(int x)
{
int r=x;
while(r!=pre[r])
r=pre[r];
//路徑壓縮
while(x!=r){
int i=pre[x];
pre[x]=r;
x=i;
}
return r;
}
struct Edge{
double l;
int u,v;
bool operator<(const Edge &a)const
{
return l<a.l;
}
}e[N*N/2];
void join(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
pre[fx]=fy;
}
int main()
{
int n,cnt=0;
while(scanf("%d",&n)&&n){
double p[N][2];
for(int i=1;i<=n;i++)
scanf("%lf%lf",&p[i][0],&p[i][1]);
//計算n個點相互之間的距離
int k=0;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
e[k].l=sqrt((p[i][0]-p[j][0])*(p[i][0]-p[j][0])+(p[i][1]-p[j][1])*(p[i][1]-p[j][1]));
e[k].u=i;
e[k].v=j;
k++;
}
sort(e,e+k);
init(n);
//從小到大加邊
for(int i=0;i<k;i++){
join(e[i].u,e[i].v);//新增邊d[i]
if(find(1)==find(2)){//新增邊d[i]後1號結點和2號結點連通了,這就是答案
printf("Scenario #%d\nFrog Distance = %.3lf\n\n",++cnt,e[i].l);
break;
}
}
}
return 0;
}