poj2253--Frogger--Kruskal

Posted BK-Edwina

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj2253--Frogger--Kruskal相关的知识,希望对你有一定的参考价值。

Description
给出两只青蛙的坐标A、B,和其他的n-2个坐标,任一两个坐标点间都是双向连通的。显然从A到B存在至少一条的通路,每一条通路的元素都是这条通路中前后两个点的距离,这些距离中又有一个最大距离。
现在要求求出所有通路的最大距离,并把这些最大距离作比较,把最小的一个最大距离作为青蛙的最小跳远距离。

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

题解:

  本题可以用二分或者kruskal来做。若是二分,抓住题中“最大边权最小”的要求,由此最优转化为判定可行解。

  也可以看作是最短路的变形应用,这里贴一发kruskal的水解法。

  首先考虑我们是如何转化到最小生成树问题的,题中的意思可以看作加若干条边,使得1和2联通。

  其次回想一下kruskal求最小生成树的过程,第一步是将边从小到大排序,再贪心加边。放到本题中,相当于依次从小到大加边,直到1和2联通为止。

  显然因为kruskal在加边时已经是从小到大的了,那么答案显然是最后加的那条边。

技术分享
  1 #include<cmath>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cstdio>
  6 using namespace std;
  7 const int maxn=1009;
  8 const int maxm=40009;
  9 
 10 int fa[maxm],tot,n;//tot记录边数
 11 double x[maxn],y[maxn],ans;
 12 
 13 struct edge
 14 {
 15     int frm,to;
 16     double w;
 17 }e[maxm];
 18 
 19 bool cmp(edge a,edge b)
 20 {
 21     return a.w<b.w;
 22 }
 23 
 24 double getlen(int a,int b)
 25 {
 26     return sqrt( (x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]) );
 27 }
 28 void init()
 29 {
 30     tot=0;
 31     for(int i=0;i<=maxn;i++)
 32     {
 33         fa[i]=i;
 34     }
 35 }
 36 
 37 int find(int x)
 38 {
 39     if(x!=fa[x])
 40         fa[x]=find(fa[x]);
 41     return fa[x];
 42 }
 43 
 44 bool same_set(int x,int y)
 45 {
 46     return find(x)==find(y);
 47 }
 48 
 49 void uni(int x,int y)
 50 {
 51     int u=find(x),v=find(y);
 52     if(u==v)return;
 53     fa[u]=v;
 54 }
 55 
 56 void kruskal()
 57 {
 58     ans=0.0;
 59     sort(e+1,e+tot+1,cmp);
 60     for(int i=1;i<=tot;i++)
 61     {
 62         if(find(1)==find(2))break;
 63         if(!same_set(e[i].frm,e[i].to))
 64         {
 65             uni(e[i].frm,e[i].to);
 66             ans=e[i].w;
 67         }
 68     }
 69 }
 70 
 71 int main()
 72 {
 73     int cas=0;
 74     while(scanf("%d",&n)!=EOF)
 75     {
 76         if(n==0)break;
 77         for(int i=1;i<=n;i++)
 78         {
 79             scanf("%lf%lf",&x[i],&y[i]);
 80         }
 81         init();
 82         for(int i=1;i<=n;i++)
 83         {
 84             for(int j=1;j<=n;j++)
 85             {
 86                 if(i==j)continue;
 87                 e[++tot].frm=i;
 88                 e[tot].to=j;
 89                 e[tot].w=getlen(i,j);
 90             }
 91         }
 92         kruskal();
 93         printf("Scenario #%d\nFrog Distance = %.3lf\n\n",++cas,ans);
 94     }
 95     return 0;
 96 }
 97 /*
 98 8
 99 0 0
100 2 4
101 0 2
102 1 0
103 2 0
104 2 1
105 2 2
106 2 3
107 
108 
109 
110 ans=1.000
111 */
View Code

 



以上是关于poj2253--Frogger--Kruskal的主要内容,如果未能解决你的问题,请参考以下文章

POJ 刷题指南

DP50题(转)

POJ题目分类

计算几何专题

计算几何专题

北大ACM - POJ试题分类