题意:河里有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. 使用 pjax 载入的新页面,新页面上 类方法 无法被触发?

    在父页面上有定义类似 $(".class").click(function(){ ... }) 经过pjax 载入后的新页面 点击后没有触发事件 在segmentfault 上提问 ...

  2. 使用chardet判断编码方式

    1. chardet是什么 chardet是python中比较常用的一个编码方式检测库,需要注意的是它只检测并返回检测结果,并不负责对原数据做什么处理. 可以使用PIP命令安装: pip instal ...

  3. VC字体对话框的初始化

    本代码需要先添加类成员  LOGFONT lf; void CMyDlg::OnButton3() { // TODO: Add your control notification handler c ...

  4. JS日历控件特效代码layDate

    https://www.js-css.cn/a/jscode/date/2015/0405/1461.html

  5. oracle数据库只查询前n条

    select * from  (select * from   tablename order by createdate desc)  aaa -- 按创建时间倒排序 where rownum &l ...

  6. 41、和为S的连续正数序列

    一.题目 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久,他 ...

  7. django框架<三>

    一.ORM操作  1.django orm创建数据库的方法 (1)指定连接pymysql(python3.x),先配置__init__.py import pymysql pymysql.instal ...

  8. 用户空间与内核空间数据交换的方式(9)------netlink【转】

    转自:http://www.cnblogs.com/hoys/archive/2011/04/10/2011722.html Netlink 是一种特殊的 socket,它是 Linux 所特有的,类 ...

  9. python RSA加密解密及模拟登录cnblog

    1.公开密钥加密 又称非对称加密,需要一对密钥,一个是私人密钥,另一个则是公开密钥.公钥加密的只能私钥解密,用于加密客户上传数据.私钥加密的数据,公钥可以解密,主要用于数字签名.详细介绍可参见维基百科 ...

  10. Unity 软件使用事项

    打开旧版工程 目前发现两种方式来触发升级程序: 1.Unity软件启动时选择旧版工程,触发更新 2.直接打开旧版工程的场景文件,触发更新   在使用中发现一种错误做法,不知道是不是共性问题,在此先记录 ...