POJ 2253 Frogger(并查集+二分)
来源:互联网 发布:二叉树的遍历 java 编辑:程序博客网 时间:2024/05/23 01:56
POJ 2253 Frogger(并查集+二分)
http://poj.org/problem?id=2253
题意:
给你N个石头的坐标(x,y),现在青蛙要从第一个石头跳到第二个石头上去(青蛙可以通过跳跃到其他石头而间接到达第2个石头上),但是青蛙每次最大的跳跃距离有限制。所以现在问你青蛙每次跳跃最少需要跳多长距离 才能 从第一个石头跳到第二个石头?
分析:
网上说这题有最短路径解的,生成树解的.本来我是冲着最短路径解法来的,但是看了一遍我觉得这题用二分+并查集(判断1点与2点是否连通)才是比较直观的方法吧.
首先我们二分出mid值表示青蛙每次能跳跃的最大距离,然后我们遍历所有的边,只要当前边的长度<=mid,就合并当前边连接的两个点所属的连通分量(因为青蛙如果在其中一点上,那么必定能调到另外一点所属分量的所有点上)。最后判断1号点与2号点是否在同一个连通分量,即可知道单次mid的跳跃距离是否足够。
AC代码(新):
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int maxn=200+5;int n;int fa[maxn];int findset(int x){ return fa[x]==-1? x:fa[x]=findset(fa[x]);}int bind(int u,int v){ int fu=findset(u); int fv=findset(v); if(fu != fv) { fa[fu]=fv; return 1; } return 0;}struct Point{ double x,y;}p[maxn];double dist[maxn][maxn];bool ok(double mid){ memset(fa,-1,sizeof(fa)); for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) if(dist[i][j]<=mid) bind(i,j); return findset(0)==findset(1);}int main(){ int kase=0; while(scanf("%d",&n)==1 && n) { for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); for(int i=0;i<n;i++) for(int j=i;j<n;j++) dist[i][j]=dist[j][i]=sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)); double L=0,R=2000; while(R-L>1e-5) { double mid = (R+L)/2; if(ok(mid)) R=mid; else L=mid; } printf("Scenario #%d\nFrog Distance = %.3lf\n\n",++kase,L); } return 0;}
AC代码:
#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>using namespace std;const int maxn=200+10;int n;double x[maxn],y[maxn];double d[maxn][maxn];int fa[maxn];int find(int i){ if(fa[i]==-1) return i; return fa[i] = find(fa[i]);}void bind(int i,int j){ i=find(i); j=find(j); if(i!=j) fa[i]=j;}bool ok(double mid){ memset(fa,-1,sizeof(fa)); for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++)if(d[i][j]<mid) bind(i,j); } return find(1)==find(2);}int main(){ int kase=0; while(scanf("%d",&n)==1&&n) { for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]); memset(d,0,sizeof(d)); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) d[i][j]=d[j][i]= sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); double L=0,R=d[1][2]; while(R-L>1e-7) //这里是1e-7 不是1e7 { double mid = (R+L)/2; if(ok(mid)) R=mid; else L=mid; } printf("Scenario #%d\nFrog Distance = %.3lf\n\n",++kase,R); } return 0;}
0 0
- POJ 2253 Frogger(并查集+二分)
- poj 2253 -- Frogger (并查集+贪心)
- poj 2253 Frogger 【枚举+并查集 or 最短路】
- 【POJ】2253 Frogger 二分+bfs
- POJ 2253 Frogger (floyd, 二分)
- 【POJ】2253 - Frogger(二分)
- [POJ 2253] Frogger [二分答案+搜索]
- POJ 2263 Heavy Cargo(二分+并查集)
- POJ-2985(树状数组 + 并查集 + 二分)
- POJ 1797 Heavy Transportation(二分+并查集/kruskal)
- POJ 3228 网络流+二分&并查集
- poj 1330 Nearest Common Ancestors(并查集?!二分查找)
- POJ 2492 二分图判断 并查集
- POJ 3657 Haybale Guessing 并查集+二分答案
- Poj 3657 Haybale Guessing(二分+并查集)
- Poj 3657 Haybale Guessing(二分+并查集)
- Poj 并查集
- poj并查集
- Windows 7/8/8.1下无线网卡MAC无法修改的解决方法
- hdu 1161 Eddy's mistakes(字符串:读入一行)
- GDB十分钟教程
- Bitcoin原始API
- 207
- POJ 2253 Frogger(并查集+二分)
- 数理统计与概率知识杂谈
- Mysql数据类型
- 多选框全选功能
- MacOSX上那些有用的小插件
- Java Socket 使用BufferedWriter和BufferedReader要注意readLine 以及换行标志
- ORACLE备份保留策略(RETENTION POLICY)
- Linux下部署svn服务器
- C++实现二叉树的非递归前、中、后序遍历