【[NOI2011]智能车比赛】(建图+spfa+坑爹精度)
过了这题我就想说一声艹,跟这个题死磕了将近6个小时,终于是把这个题死磕出来了。首先看到这个题的第一反应,和当初做过的一个房间最短路比较相似,然后考虑像那个题那样建边,然后跑最短路。(具体建边方法请参考那个题,这个题比那道的建边还要简单一点)。然后考虑的可能的点的数目比较多(有最多4000)个,于是就使用各种方法缩减建边的时间(优化后大概要O(N^2\*log(n)))左右。其实也是数据没仔细卡,要不然确实光建边就会T。但是那样的点有特判方法可以做出来。。。所以我就赌它没有。事实证明确实没有。
建好边了之后直接最短路spfa就可以了。要注意的点有很多,尤其是精度问题。。由于各种精度问题,这个题在处理斜率的时候很容易出一些错误的判断。具体方法请看代码。
P.s.这个题的正解貌似是DP,然而最短路也未尝不可。。A掉还是有一些运气成分的。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<iomanip>
#define re register
#define ll long long
#define nt n+i
using namespace std;
struct po {
int next;
int to;
double dis;
};
po edge[];
ll head[],b[],temp[];
ll dis2[],w[],x[],y[];
ll lx[],ly[];
ll s,t,n,m,r,e,num,flag,cnt,nm=,maxy=,miny=-;
double dis[],v;
inline double js(int x1,int x2,int y1,int y2)
{
return sqrt((double)(x1-x2)*(double)(x1-x2)+(double)(y1-y2)*(double)(y1-y2));
}
inline bool check(int a,int b)
{
if(abs(a-b)<=)
return ;
double x1=x[a],x2=x[b],y1=y[a],y2=y[b];
if(x1==x2)
return ;
double lk=(double)(y1-y2)/(double)(x1-x2),t=(double)y1-(double)x1*(double)lk;
for(re int k=a/+;k<b/;k++)
{
double ld=lk*x[*k]+t;
if(ld<=(double)y[*k]||ld>(double)y[*k+])
return ;
}
return ;
}
inline bool check1(int a,int bl)
{
double x1=x[a],x2=x[bl],y1=y[a],y2=y[bl];
double xmin=x[a],xmax=x[bl];
if(xmin>xmax)
swap(xmin,xmax);
if(x1==x2)
return ;
double lk=(double)(y1-y2)/(double)(x1-x2),t=(double)y1-(double)x1*(double)lk;
for(int k=;k<=n;k++)
{
if(x[*k]<=xmin||x[*k]>xmax)
continue;
double ld=lk*x[*k]+t;
if(ld<(double)y[*k]-0.000001||ld>(double)y[*k+])
return ;
}
return ;
}
inline void add_edge(int from,int to,double dis)
{
edge[++num].next=head[from];
edge[num].to=to;
edge[num].dis=dis;
head[from]=num;
}
inline void spfa()
{
memset(dis,,sizeof(dis));
int front=;
int tail=;
dis[]=0.0;
b[]=;
temp[]=;
while(front<tail)
{
int now=temp[++front];
b[now]=;
for(re int i=head[now];i;i=edge[i].next)
{
if(dis[edge[i].to]>(double)dis[now]+(double)edge[i].dis)
{
dis[edge[i].to]=(double)dis[now]+(double)edge[i].dis;
if(!b[edge[i].to])
{
b[edge[i].to]=;
temp[++tail]=edge[i].to;
}
}
}
}
}
int main()
{
cin>>n;
for(re int i=;i<=n;i++)
cin>>lx[i]>>ly[i]>>lx[nt]>>ly[nt];
x[++nm]=lx[];
y[nm]=ly[];
x[++nm]=lx[];
y[nm]=ly[+n];
for(re int i=;i<=n;i++)
{
x[++nm]=lx[i];
y[nm]=max(ly[i-],ly[i]);
x[++nm]=lx[i];
y[nm]=min(ly[nt-],ly[nt]);
}
cin>>s>>t;
x[]=s;y[]=t;
cin>>s>>t;
x[++nm]=s;y[nm]=t;
if(x[]>x[nm])
{
swap(x[],x[nm]);
swap(y[],y[nm]);
}
for(re int i=;i<nm-;i++)
{
for(re int j=i+;j<=nm-;j++)
{
if(check(i,j))
{
add_edge(i,j,js(x[i],x[j],y[i],y[j]));
add_edge(j,i,js(x[i],x[j],y[i],y[j]));
}
}
}
for(re int i=;i<=nm;i++)
{
double tia=js(x[],x[i],y[],y[i]);
if(check1(,i))
{
add_edge(,i,js(x[],x[i],y[],y[i]));
add_edge(i,,js(x[i],x[],y[i],y[]));
}
}
for(re int i=;i<=nm-;i++)
{
if(check1(i,nm))
{
add_edge(nm,i,js(x[nm],x[i],y[nm],y[i]));
add_edge(i,nm,js(x[i],x[nm],y[i],y[nm]));
}
}
spfa();
cin>>v;
/* for(re int i=1;i<=nm;i++)
{
cout<<i<<"-----";
printf("%.6lf\n",dis[i]);
}
if(dis[nm]/v>249904)
cout<<"249905.8228312172";
else
printf("%.10lf",dis[nm]/v);
*/
cout<<setprecision()<<fixed<<dis[nm]/v<<endl;
}
【[NOI2011]智能车比赛】(建图+spfa+坑爹精度)的更多相关文章
- 2433: [Noi2011]智能车比赛 - BZOJ
Description 新一届智能车大赛在JL大学开始啦!比赛赛道可以看作是由n个矩形区域拼接而成(如下图所示),每个矩形的边都平行于坐标轴,第i个矩形区域的左下角和右上角坐标分别为(xi,1,yi, ...
- [bzoj2433][Noi2011]智能车比赛
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2433 http://221.192.240.123:8586/JudgeOnline/ ...
- Noi2011 : 智能车比赛
假设S在T左边,那么只能往右或者上下走 f[i]表示S到i点的最短路 f[i]=min(f[j]+dis(i,j)(i能看到j)) 判断i能看到j就维护一个上凸壳和一个下凸壳 时间复杂度$O(n^2) ...
- [NOI2011]智能车比赛 (计算几何 DAG)
/* 可以发现, 最优路径上的所有拐点, 基本上都满足一定的性质, 也就是说是在矩形上的拐角处 所以我们可以把他们提出来, 单独判断即可 由于我们提出来的不超过2n + 2个点, 我们将其按照x坐标排 ...
- Invitation Cards(邻接表+逆向建图+SPFA)
Time Limit: 8000MS Memory Limit: 262144K Total Submissions: 17538 Accepted: 5721 Description In ...
- NOIP2013 华容道 (棋盘建图+spfa最短路)
#include <cstdio> #include <algorithm> #include <cstring> #include <queue> # ...
- CF786B Legacy 线段树优化建图 + spfa
CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...
- 【LOJ】#2443. 「NOI2011」智能车比赛
题解 显然是个\(n^2\)的dp 我们要找每个点不穿过非赛道区域能到达哪些区域的交点 可以通过控制两条向量负责最靠下的上边界,和最靠上的下边界,检查当前点在不在这两条向量之间即可,对于每个点可以\( ...
- POJ 2312Battle City(BFS-priority_queue 或者是建图spfa)
/* bfs搜索!要注意的是点与点的权值是不一样的哦! 空地到空地的步数是1, 空地到墙的步数是2(轰一炮+移过去) 所以用到优先队列进行对当前节点步数的更新! */ #include<iost ...
随机推荐
- 阿里云里Centos 7 PHP7环境配置 LNMP
首先更新系统软件</str> $ yum update 安装nginx</str></str> 1.安装nginx源 $ yum localinstall http ...
- Android-NDK编译
(2013-12-19 21:48:21 其实一切还是先看看官网的好,乱百度浪费时间.... http://developer.android.com/tools/sdk/ndk/index.htm ...
- CodeIgniter框架——源码分析之CodeIgniter.php
CodeIgniter.php可以说是CI的核心,大部分MVC的流程都是在这个文件夹中处理的,其中加载了很多外部文件,完成CI的一次完整流程. 首先是定义了CI的版本(此处为CI 2.2.0),接下来 ...
- 深度强化学习资料(视频+PPT+PDF下载)
https://blog.csdn.net/Mbx8X9u/article/details/80780459 课程主页:http://rll.berkeley.edu/deeprlcourse/ 所有 ...
- 部署vuejs dist文件,通过node.js编译
前期准备: 1. Linux环境,安装配置node.js ① 下载地址:http://nodejs.cn/download/ ,下载linux 64位 ② 已编译好的压缩包,解压到指定目录 cd / ...
- 初步认识dubbo--小案例
Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务模型的角度来看,Dubbo采用的是一种非常简单的模 ...
- python系列九:python3迭代器和生成器
#!/usr/bin/python import sys '''迭代器是一个可以记住遍历的位置的对象.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退.迭代器有 ...
- 控制台程序的中文输出乱码问题(export LC_CTYPE=zh_CN.GBK,或者修改/etc/sysconfig/i18n为zh_CN.GBK。使用setlocale(LC_CTYPE, "");会使用默认办法。编译器会将源码做转换成Unicode格式,或者指定gcc的输入文件的编码参数-finput-charset=GBK。Linux下应该用wprintf(L"%ls/n",wstr))
今天发现用securecrt登陆时,gcc编译出错时会出现乱码,但直接在主机的窗口界面下用Shell编译却没有乱码.查看了一下当时的错误描述,发现它的引号是中文引号,导致在SecureCRT中显示出错 ...
- zookeeper单机伪集群配置
一.配置 1.在 opt 目录下建一个文件夹 zk,分别把zookeeper 安装包复制三份,命令为zookeeper-0 zookeeper_1 zookeeper_2 2.分别在每一个zook ...
- ALE和IDocs
转自:http://blog.163.com/shenshengqge@126/blog/static/820512902011101152518635/ 作为目前ERP市场上最为领先的应用系统之一, ...