过了这题我就想说一声艹,跟这个题死磕了将近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+坑爹精度)的更多相关文章

  1. 2433: [Noi2011]智能车比赛 - BZOJ

    Description 新一届智能车大赛在JL大学开始啦!比赛赛道可以看作是由n个矩形区域拼接而成(如下图所示),每个矩形的边都平行于坐标轴,第i个矩形区域的左下角和右上角坐标分别为(xi,1,yi, ...

  2. [bzoj2433][Noi2011]智能车比赛

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2433 http://221.192.240.123:8586/JudgeOnline/ ...

  3. Noi2011 : 智能车比赛

    假设S在T左边,那么只能往右或者上下走 f[i]表示S到i点的最短路 f[i]=min(f[j]+dis(i,j)(i能看到j)) 判断i能看到j就维护一个上凸壳和一个下凸壳 时间复杂度$O(n^2) ...

  4. [NOI2011]智能车比赛 (计算几何 DAG)

    /* 可以发现, 最优路径上的所有拐点, 基本上都满足一定的性质, 也就是说是在矩形上的拐角处 所以我们可以把他们提出来, 单独判断即可 由于我们提出来的不超过2n + 2个点, 我们将其按照x坐标排 ...

  5. Invitation Cards(邻接表+逆向建图+SPFA)

    Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 17538   Accepted: 5721 Description In ...

  6. NOIP2013 华容道 (棋盘建图+spfa最短路)

    #include <cstdio> #include <algorithm> #include <cstring> #include <queue> # ...

  7. CF786B Legacy 线段树优化建图 + spfa

    CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...

  8. 【LOJ】#2443. 「NOI2011」智能车比赛

    题解 显然是个\(n^2\)的dp 我们要找每个点不穿过非赛道区域能到达哪些区域的交点 可以通过控制两条向量负责最靠下的上边界,和最靠上的下边界,检查当前点在不在这两条向量之间即可,对于每个点可以\( ...

  9. POJ 2312Battle City(BFS-priority_queue 或者是建图spfa)

    /* bfs搜索!要注意的是点与点的权值是不一样的哦! 空地到空地的步数是1, 空地到墙的步数是2(轰一炮+移过去) 所以用到优先队列进行对当前节点步数的更新! */ #include<iost ...

随机推荐

  1. 机器学习之猫狗大战,解决image RGB values must be in the 0..1 range.

    猫狗大战是比较经典的机器学习案例,前几天体验了一番,来记录一下 1.图片准备 首先是准备训练的图片 链接:https://pan.baidu.com/s/1ht1HIuw 密码:aw9s 2.开始训练 ...

  2. eclipse + pydev 创建django项目

    前提条件机器装好python,并装好django插件.(http://blog.csdn.net/lilongjiu/article/details/51405340) 1. 下载eclise Ver ...

  3. POJ3090

    Visible Lattice Points Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7094   Accepted: ...

  4. EasyPlayer.js网页全终端播放器安装使用文档

    EasyPlayer.js 集 rtmp, hls, flv, websocket 于一身的网页直播/点播播放器, 使用简单, 功能强大 属性(Property) video-url 视频流地址 St ...

  5. <..................> 哈佛大学哲学系 && 历史哲学笔记文献集

    哈佛大学哲学系课程表            (一)概况    (1)哈佛大学哲学系现有教师21人,其中访问教授7人,教师流动性较大,每年有一定的变化.以下为现任教师:Richard Moran(系主任 ...

  6. 解决Oracle安装时报错“SID已在使用”办法

    1. 开始->设置->控制面板->管理工具->服务 停止所有Oracle服务. 2. 开始->程序->Oracle - OraHome81->Oracle I ...

  7. 插叙LTE-2

      LTE TDD与LTE FDD技术简介和比较 标签: 频分双工(FDD) 时分双工(TDD) LTE 摘要:UTRA 的长期演进(Long Term Evolution ,LTE) 技术存在LTE ...

  8. ./bin/console server:run Surprise! There are no commands defined in the "server" namespace.

    Let's start the built-in web server:   ./bin/console server:run Surprise! There are no commands defi ...

  9. python基础28 -----python中sockserver模块

    一.Python中的sockserver模块 1.该模块与sock模块不同之处是该模块自动帮我们分装好了一些功能,让我们在编程的时候直接调用这些功能就可以了,节省了编程步骤. 2.如图所示 注释:上图 ...

  10. 剑指offer 面试37题

    面试37题: 题:序列化二叉树 题目:请实现两个函数,分别用来序列化和反序列化二叉树 解题思路:首先来看二叉树的序列化,二叉树的序列化就是采用前序遍历二叉树输出节点,再碰到左子节点或者右子节点为Non ...