【[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 ...
随机推荐
- Android Studio使用心得 - 常见问题集锦
FBI Warning:欢迎转载,但请标明出处:http://blog.csdn.net/codezjx/article/details/38669939,未经本人允许请勿用于商业用途,感谢支持! 整 ...
- linux 大量的TIME_WAIT解决办法(转)
发现存在大量TIME_WAIT状态的连接tcp 0 0 127.0.0.1:3306 127.0.0.1:41378 TIME ...
- Ubuntu下安装phpMyAdmin
首先添加必要的apt源 1 apt-get update 确保软件包列表是最新的 apt-get upgrade 更新软件包 安装phpMyAdmin apt-get install phpmyadm ...
- Martin Fowler’s Active Record design pattern.
P of EAA: Active Record https://www.martinfowler.com/eaaCatalog/activeRecord.html Active Record An o ...
- 在Tomcat配置JNDI数据源的三种方式
最近使用到了在tomcat下配置数据源的内容,在这里转载一篇文章记录下 转载自: http://blog.csdn.net/dyllove98/article/details/7706218 在我过去 ...
- pc端监听屏幕实现导航固定定位
要点:占位符 js,监听屏幕滚动事件,当滚动条距离浏览器顶部的距离 大于 要固定定位开始以下元素的距离,则给要固定元素添加fixed样式. 初始化方法时,要给占位符添加样式 function sort ...
- 类加载器(ClassLoader)
1. 类加载器概述 1.1 类加载器的作用 把 .class 文件加载到 JVM 的方法区中,变成一个 Class 对象! 1.2 类加载器分类 类加载器也是一个类: ClassLoader; Jav ...
- Python3.6全栈开发实例[006]
6.检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者. dic = {"k1": "v1v1", " ...
- Activity重要函数
一.onConfigurationChanged 与 android:configChanges Lists configuration changes that the activity will ...
- 4.1 使用STM32控制MC20拨打电话
需要准备的硬件 MC20开发板 1个 https://item.taobao.com/item.htm?id=562661881042 GSM/GPRS天线 1根 https://item.taoba ...