题意:河里有n块石头,一只青蛙要从左岸跳到右岸,你可以再在任意一个位置放一块石头,使得在最优方案下,青蛙单步跳的距离的最大值最小化,输出该位置。

将原图视作完全图,二分答案mid,然后在图中只保留小于等于mid的边,分别用dfs处理左岸能到哪些石头,右岸能到哪些石头。然后二重循环枚举两侧这些点对,如果存在一对点,它们的距离不超过2*mid,那么mid可行,将石头放在它们的中点即可。否则不可行。

要注意,左岸和右岸也需要当成点,不过距离计算时会稍微麻烦一点,需要讨论一下。

#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const double EPS=0.001;
struct Point{
ll x,y;
Point(const ll &x,const ll &y){
this->x=x;
this->y=y;
}
Point(){}
double length(){
return sqrt((double)x*(double)x+(double)y*(double)y);
}
void read(){
scanf("%lld%lld",&x,&y);
}
}p[1005];
typedef Point Vector;
Vector operator - (const Point &a,const Point &b){
return Vector(a.x-b.x,a.y-b.y);
}
int n,m;
double dis(int i,int j){
if(i==0 && j==0 || i==m+1 && j==m+1){
return 0.0;
}
if(i==0 && j==m+1 || i==m+1 && j==0){
return (double)n;
}
if(i==0){
return (double)p[j].x;
}
if(j==0){
return (double)p[i].x;
}
if(i==m+1){
return (double)(n-p[j].x);
}
if(j==m+1){
return (double)(n-p[i].x);
}
return (p[i]-p[j]).length();
}
double mid;
bool can[2][1005];
void dfs(int U){
can[0][U]=1;
for(int i=1;i<=m;++i){
if(!can[0][i] && dis(U,i)-mid<EPS){
dfs(i);
}
}
}
void df2(int U){
can[1][U]=1;
for(int i=1;i<=m;++i){
if(!can[1][i] && dis(U,i)-mid<EPS){
df2(i);
}
}
}
int main(){
freopen("froggy.in","r",stdin);
freopen("froggy.out","w",stdout);
scanf("%d%d",&n,&m);
if(m==0){
printf("%.3f %.3f\n",(double)n*0.5,1.0);
return 0;
}
for(int i=1;i<=m;++i){
p[i].read();
}
double l=0.0,r=(double)n;
double anx,any;
while(r-l>EPS){
memset(can,0,sizeof(can));
mid=(l+r)*0.5;
dfs(0);
df2(m+1);
bool flag=0;
for(int i=0;i<=m+1;++i){
bool ok=0;
for(int j=0;j<=m+1;++j){
if(can[0][i] && can[1][j] && dis(i,j)-2.0*mid<EPS){
ok=1;
if(i==0 && j==m+1 || i==m+1 && j==0){
anx=(double)n*0.5;
any=1.0;
}
else if(i==0 && j==0){
continue;
}
else if(i==m+1 && j==m+1){
anx=(double)n;
any=0.0;
}
else if(i==0){
anx=(double)p[j].x*0.5;
any=(double)p[j].y;
}
else if(j==0){
anx=(double)p[i].x*0.5;
any=(double)p[i].y;
}
else if(i==m+1){
anx=(double)(p[j].x+n)*0.5;
any=(double)p[j].y;
}
else if(j==m+1){
anx=(double)(p[i].x+n)*0.5;
any=(double)p[i].y;
}
else{
anx=(double)(p[i].x+p[j].x)*0.5;
any=(double)(p[i].y+p[j].y)*0.5;
}
break;
}
}
if(ok){
flag=1;
break;
}
}
if(flag){
r=mid;
}
else{
l=mid+EPS;
}
}
printf("%.3f %.3f\n",anx,any);
return 0;
}

【二分答案】【DFS】【分类讨论】Gym - 100851F - Froggy Ford的更多相关文章

  1. Gym - 100851F Froggy Ford kruskal

    题目链接: http://acm.hust.edu.cn/vjudge/problem/307216 Froggy Ford Time Limit: 3000MS 题意 青蛙过河,河中有若干个石头,现 ...

  2. Gym - 100851F - Froggy Ford(dijkstra)

    题目链接 参考   http://blog.csdn.net/KIJamesQi/article/details/52214990 题意 蛤蛤要从这岸去到对岸,河中有n块石头,现可以在河中添加一块石头 ...

  3. CH Round #72树洞[二分答案 DFS&&BFS]

    树洞 CH Round #72 - NOIP夏季划水赛 描述 在一片栖息地上有N棵树,每棵树下住着一只兔子,有M条路径连接这些树.更特殊地是,只有一棵树有3条或更多的路径与它相连,其它的树只有1条或2 ...

  4. BZOJ 1486: [HNOI2009]最小圈( 二分答案 + dfs判负圈 )

    二分答案m, 然后全部边权减掉m, 假如存在负圈, 那么说明有平均值更小的圈存在. 负圈用dfs判断. ------------------------------------------------ ...

  5. dp+分类讨论 Gym 101128E

    题目链接:http://codeforces.com/gym/101128 感觉这个人写的不错的(我只看了题目大意):http://blog.csdn.net/v5zsq/article/detail ...

  6. [BZOJ 1486][HNOI2009]最小圈(二分答案+dfs写的spfa判负环)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1486 分析:容易想到先二分答案x,然后把所有边的权值-x,那么如果图中存在权值和为0的 ...

  7. 【树链剖分】【dfs序】【LCA】【分类讨论】Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground

    一棵树,q次询问,每次给你三个点a b c,让你把它们选做s f t,问你把s到f +1后,询问f到t的和,然后可能的最大值是多少. 最无脑的想法是链剖线段树……但是会TLE. LCT一样无脑,但是少 ...

  8. 【AtCoder Grand Contest 007E】Shik and Travel [Dfs][二分答案]

    Shik and Travel Time Limit: 50 Sec  Memory Limit: 512 MB Description 给定一棵n个点的树,保证一个点出度为2/0. 遍历一遍,要求每 ...

  9. Gym - 101908G 二分答案+最大流

    After the end of the truck drivers' strike, you and the rest of Nlogônia logistics specialists now h ...

随机推荐

  1. mysql查询日期相关的

    今天 select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天 SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ...

  2. Java读取大文件的高效率实现

    1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 ...

  3. tensorflow.nn.bidirectional_dynamic_rnn()函数的用法

    在分析Attention-over-attention源码过程中,对于tensorflow.nn.bidirectional_dynamic_rnn()函数的总结: 首先来看一下,函数: def bi ...

  4. 【Python学习】字符编码

    先说两个基础知识. (1)计算机内部,数据是由0,1组成的: (2)计算机最小的数据单位,就是一个二进制单位即bit,接下来就是8个二进制单位表示一个字节(Byte). 1 ASCII码 ASCII码 ...

  5. Nim 游戏、SG 函数、游戏的和

    Nim游戏 Nim游戏定义 Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于“Impartial Combinatorial Games”(以下简称ICG).满足以 ...

  6. C中常用格式格式码

    一.常用printf格式码 二.常用scanf格式码

  7. web deploy 安装失败解决

    单独运行安装包,提示脚本运行失败. VS安装提示解包失败. 解决:检查Windows Management Instrumentation服务状态.需要非禁用.

  8. Python学习笔记——迭代器和生成器

    1.手动遍历迭代器 使用next函数,并捕获StopIteration异常. def manual_iter(): with open('./test.py') as f: try: while Tr ...

  9. 关于U3D中的移动和旋转

    关于移动,其实很简单,就是移动: 第一个参数标识移动的距离,是一个矢量:第二个参数是因为游戏对象有自己的坐标系,还有一个世界坐标系,使用的坐标系不同将导致运动的结果不同: function Trans ...

  10. hdu 5875(单调栈)

    Function Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...