过了这题我就想说一声艹,跟这个题死磕了将近6个小时,终于是把这个题死磕出来了。首先看到这个题的第一反应,和当初做过的一个房间最短路比较相似,然后考虑像那个题那样建边,然后跑最短路。(具体建边方法请参考那个题,这个题比那道的建边还要简单一点)。然后考虑的可能的点的数目比较多(有最多4000)个,于是就使用各种方法缩减建边的时间(优化后大概要O(N^2\*log(n)))左右。其实也是数据没仔细卡,要不然确实光建边就会T。但是那样的点有特判方法可以做出来。。。所以我就赌它没有。事实证明确实没有。

建好边了之后直接最短路spfa就可以了。要注意的点有很多,尤其是精度问题。。由于各种精度问题,这个题在处理斜率的时候很容易出一些错误的判断。具体方法请看代码。

P.s.这个题的正解貌似是DP,然而最短路也未尝不可。。A掉还是有一些运气成分的。。。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<algorithm>
  6. #include<queue>
  7. #include<iomanip>
  8. #define re register
  9. #define ll long long
  10. #define nt n+i
  11. using namespace std;
  12. struct po {
  13. int next;
  14. int to;
  15. double dis;
  16. };
  17. po edge[];
  18. ll head[],b[],temp[];
  19. ll dis2[],w[],x[],y[];
  20. ll lx[],ly[];
  21. ll s,t,n,m,r,e,num,flag,cnt,nm=,maxy=,miny=-;
  22. double dis[],v;
  23. inline double js(int x1,int x2,int y1,int y2)
  24. {
  25. return sqrt((double)(x1-x2)*(double)(x1-x2)+(double)(y1-y2)*(double)(y1-y2));
  26. }
  27. inline bool check(int a,int b)
  28. {
  29. if(abs(a-b)<=)
  30. return ;
  31. double x1=x[a],x2=x[b],y1=y[a],y2=y[b];
  32. if(x1==x2)
  33. return ;
  34. double lk=(double)(y1-y2)/(double)(x1-x2),t=(double)y1-(double)x1*(double)lk;
  35. for(re int k=a/+;k<b/;k++)
  36. {
  37. double ld=lk*x[*k]+t;
  38. if(ld<=(double)y[*k]||ld>(double)y[*k+])
  39. return ;
  40. }
  41. return ;
  42. }
  43. inline bool check1(int a,int bl)
  44. {
  45. double x1=x[a],x2=x[bl],y1=y[a],y2=y[bl];
  46. double xmin=x[a],xmax=x[bl];
  47. if(xmin>xmax)
  48. swap(xmin,xmax);
  49. if(x1==x2)
  50. return ;
  51. double lk=(double)(y1-y2)/(double)(x1-x2),t=(double)y1-(double)x1*(double)lk;
  52. for(int k=;k<=n;k++)
  53. {
  54. if(x[*k]<=xmin||x[*k]>xmax)
  55. continue;
  56. double ld=lk*x[*k]+t;
  57. if(ld<(double)y[*k]-0.000001||ld>(double)y[*k+])
  58. return ;
  59. }
  60. return ;
  61. }
  62. inline void add_edge(int from,int to,double dis)
  63. {
  64. edge[++num].next=head[from];
  65. edge[num].to=to;
  66. edge[num].dis=dis;
  67. head[from]=num;
  68. }
  69. inline void spfa()
  70. {
  71. memset(dis,,sizeof(dis));
  72. int front=;
  73. int tail=;
  74. dis[]=0.0;
  75. b[]=;
  76. temp[]=;
  77. while(front<tail)
  78. {
  79. int now=temp[++front];
  80. b[now]=;
  81. for(re int i=head[now];i;i=edge[i].next)
  82. {
  83. if(dis[edge[i].to]>(double)dis[now]+(double)edge[i].dis)
  84. {
  85. dis[edge[i].to]=(double)dis[now]+(double)edge[i].dis;
  86. if(!b[edge[i].to])
  87. {
  88. b[edge[i].to]=;
  89. temp[++tail]=edge[i].to;
  90. }
  91. }
  92. }
  93. }
  94. }
  95. int main()
  96. {
  97. cin>>n;
  98. for(re int i=;i<=n;i++)
  99. cin>>lx[i]>>ly[i]>>lx[nt]>>ly[nt];
  100. x[++nm]=lx[];
  101. y[nm]=ly[];
  102. x[++nm]=lx[];
  103. y[nm]=ly[+n];
  104. for(re int i=;i<=n;i++)
  105. {
  106. x[++nm]=lx[i];
  107. y[nm]=max(ly[i-],ly[i]);
  108. x[++nm]=lx[i];
  109. y[nm]=min(ly[nt-],ly[nt]);
  110. }
  111. cin>>s>>t;
  112. x[]=s;y[]=t;
  113. cin>>s>>t;
  114. x[++nm]=s;y[nm]=t;
  115. if(x[]>x[nm])
  116. {
  117. swap(x[],x[nm]);
  118. swap(y[],y[nm]);
  119. }
  120. for(re int i=;i<nm-;i++)
  121. {
  122. for(re int j=i+;j<=nm-;j++)
  123. {
  124. if(check(i,j))
  125. {
  126. add_edge(i,j,js(x[i],x[j],y[i],y[j]));
  127. add_edge(j,i,js(x[i],x[j],y[i],y[j]));
  128. }
  129. }
  130. }
  131. for(re int i=;i<=nm;i++)
  132. {
  133. double tia=js(x[],x[i],y[],y[i]);
  134. if(check1(,i))
  135. {
  136. add_edge(,i,js(x[],x[i],y[],y[i]));
  137. add_edge(i,,js(x[i],x[],y[i],y[]));
  138. }
  139. }
  140. for(re int i=;i<=nm-;i++)
  141. {
  142. if(check1(i,nm))
  143. {
  144. add_edge(nm,i,js(x[nm],x[i],y[nm],y[i]));
  145. add_edge(i,nm,js(x[i],x[nm],y[i],y[nm]));
  146. }
  147. }
  148. spfa();
  149. cin>>v;
  150. /* for(re int i=1;i<=nm;i++)
  151. {
  152. cout<<i<<"-----";
  153. printf("%.6lf\n",dis[i]);
  154. }
  155. if(dis[nm]/v>249904)
  156. cout<<"249905.8228312172";
  157. else
  158. printf("%.10lf",dis[nm]/v);
  159. */
  160. cout<<setprecision()<<fixed<<dis[nm]/v<<endl;
  161. }

【[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. 多个 python的pip版本选择

    如果你电脑里面装了多个版本的python python3 -m pip instatll xlutilspython2 -m pip instatll xlutils 加载新的pippython -m ...

  2. 关于在react和node中,经常出现的const

    const是定义一个常量,在ECM6当中,定义局部变量可以用let.定义全局变量用var......这是ECM6的新特性,好吧,包子在这里只是记录一下,希望大家在将来写react或者node的时候,不 ...

  3. C#关于AutoResetEvent的使用介绍----修正

    说明 之前在博客园看到有位仁兄发表一篇关于AutoResetEvent介绍,看了下他写的代码,看上去没什么问题,但仔细看还是能发现问题.下图是这位仁兄代码截图. 仁兄博客地址:http://www.c ...

  4. dev 小问题列表

    1. MemoEdit > Lines Text lines are separated by line feed and carriage return characters ("\ ...

  5. 虚拟研讨会:如何设计好的RESTful API(转)

    原文:虚拟研讨会:如何设计好的RESTful API? REST架构风格最初由Roy T. Fielding(HTTP/1.1协议专家组负责人)在其2000年的博士学位论文中提出.HTTP就是该架构风 ...

  6. Linux考试题附答案

    一.选择题 1.在登录Linux时,一个具有唯一进程ID号的shell将被调用,这个ID是什么(B)? A.NID B.PID C.UID D.CID 2.下面哪个目录存放用户密码信息(B) A./b ...

  7. 前端基础-html(1)

    写在前面: 前端               后端 C(client)        S(server) B(browser)      S(server) 以用户为出发点 一.web标准 1)web ...

  8. /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15"" not found

    解决错误 呈现该错误的原因是当前的GCC版本中,没有GLIBCXX_3.4.15,须要安装更高版本. 我们可以输入:strings /usr/lib/libstdc++.so.6 | grep GLI ...

  9. 我的第二个Python小程序

    输出0-100之间的偶数: # Author: fansik # Description: Output an even number between 0 and 100 # method one n ...

  10. PyQt4调用UI文件

    方法1,转换到py调用 指令 pyuic4 test.ui -o testUi.py 方法2.直接调用ui文件 # -*- coding: utf-8 -*- """ - ...