不说了。。。说多了都是泪。。。从昨天下午一直wa到现在,直到刚刚才让人帮我找到所谓的“bug”,其实也算不上bug。。。

这个题的思路就是:找出平面上的所有点:所有圆的交点以及所有圆的圆心。然后依次判断两点是否连通,连通的话两点距离便是其欧几里得距离。这样建完图之后直接跑s->t最短路就行了。。

两点连通?也就是说这两点连成的线段,一直在圆内,任意圆都行。如何判断呢,求出该线段与所有圆的所有交点,排序后将其分段,依次判断每一段是否在任意圆内。这个么,在分段后,判断每一段的中点是否在圆内就行了。

这题并不是很难啊?我的bug在哪??刚开始我是将所有圆的圆心都加到平面点集中,wa到死有木有。。。刚刚改了改,只加第一个跟最后一个圆的圆心。。立A。。为什么?

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<fstream>
  5. #include<sstream>
  6. #include<vector>
  7. #include<string>
  8. #include<cstdio>
  9. #include<bitset>
  10. #include<queue>
  11. #include<stack>
  12. #include<cmath>
  13. #include<map>
  14. #include<set>
  15. #define FF(i, a, b) for(int i=a; i<b; i++)
  16. #define FD(i, a, b) for(int i=a; i>=b; i--)
  17. #define REP(i, n) for(int i=0; i<n; i++)
  18. #define CLR(a, b) memset(a, b, sizeof(a))
  19. #define LL long long
  20. #define PB push_back
  21. #define eps 1e-10
  22. #define debug puts("**debug**")
  23. using namespace std;
  24.  
  25. const double PI = acos(-1);
  26. const double INF = 1e20;
  27. const int maxn = 11111;
  28. struct Point
  29. {
  30. double x, y;
  31. Point (double x=0, double y=0):x(x), y(y) {}
  32. };
  33. typedef Point Vector;
  34.  
  35. struct Circle
  36. {
  37. Point c;
  38. double r;
  39. Circle() {}
  40. Circle(Point c, double r) : c(c), r(r) {}
  41. Point point(double a) { return Point(c.x+cos(a)*r, c.y+sin(a)*r); }
  42. };
  43.  
  44. struct Line
  45. {
  46. Point p;
  47. Vector v;
  48. double ang;
  49. Line(){}
  50. Line(Point p, Vector v) : p(p), v(v) {ang = atan2(v.y, v.x); }
  51. Point point(double t)
  52. {
  53. return Point(p.x + t*v.x, p.y + t*v.y);
  54. }
  55. bool operator < (const Line& L) const
  56. {
  57. return ang < L.ang;
  58. }
  59. };
  60.  
  61. template <class T> T sqr(T x) { return x * x;}
  62. Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }
  63. Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }
  64. Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
  65. Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
  66. bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }
  67. bool operator >= (const Point& a, const Point& b) { return a.x >= b.x && a.y >= b.y; }
  68. bool operator <= (const Point& a, const Point& b) { return a.x <= b.x && a.y <= b.y; }
  69. int dcmp(double x)
  70. {
  71. if(fabs(x) < eps) return 0;
  72. return x < 0 ? -1 : 1;
  73. }
  74. bool operator == (const Point& a, const Point& b){ return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;}
  75.  
  76. double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
  77. double Length(Vector A) { return sqrt(Dot(A, A)); }
  78. double Angel(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
  79. double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
  80. Vector vecunit(Vector x){ return x / Length(x);}
  81. Vector normal(Vector x) { return Point(-x.y, x.x) / Length(x);}
  82. double angel(Vector v) { return atan2(v.y, v.x); }
  83.  
  84. bool OnSegment(Point p, Point a1, Point a2)
  85. {
  86. return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
  87. }
  88. bool InCircle(Point x, Circle c) { return dcmp(sqr(c.r) - sqr(Length(c.c - x))) > 0;}
  89.  
  90. double DistanceToSeg(Point p, Point a, Point b)
  91. {
  92. if(a == b) return Length(p-a);
  93. Vector v1 = b-a, v2 = p-a, v3 = p-b;
  94. if(dcmp(Dot(v1, v2)) < 0) return Length(v2);
  95. if(dcmp(Dot(v1, v3)) > 0) return Length(v3);
  96. return fabs(Cross(v1, v2)) / Length(v1);
  97. }
  98.  
  99. void getLineABC(Point A, Point B, double& a, double& b, double& c)
  100. {
  101. a = A.y-B.y, b = B.x-A.x, c = A.x*B.y-A.y*B.x;
  102. }
  103.  
  104. Point GetIntersection(Line a, Line b)
  105. {
  106. Vector u = a.p-b.p;
  107. double t = Cross(b.v, u) / Cross(a.v, b.v);
  108. return a.p + a.v*t;
  109. }
  110.  
  111. int getCCintersection(Circle C1, Circle C2, vector<Point>& sol)
  112. {
  113. double d = Length(C1.c - C2.c);
  114. if(dcmp(d) == 0)
  115. {
  116. if(dcmp(C1.r - C2.r) == 0) return -1;
  117. return 0;
  118. }
  119. if(dcmp(C1.r + C2.r - d) < 0) return 0;
  120. if(dcmp(fabs(C1.r - C2.r) - d) > 0) return 0;
  121.  
  122. double a = angel(C2.c - C1.c);
  123. double da = acos((sqr(C1.r) + sqr(d) - sqr(C2.r)) / (2*C1.r*d));
  124.  
  125. Point p1 = C1.point(a-da), p2 = C1.point(a+da);
  126. sol.PB(p1);
  127. if(p1 == p2) return 1;
  128. sol.PB(p2);
  129. return 2;
  130. }
  131.  
  132. int getSegCircleIntersection(Line L, Circle C, Point* sol)
  133. {
  134. Vector nor = normal(L.v);
  135. Line pl = Line(C.c, nor);
  136. Point ip = GetIntersection(pl, L);
  137. double dis = Length(ip - C.c);
  138. if (dcmp(dis - C.r) > 0) return 0;
  139. Point dxy = vecunit(L.v) * sqrt(sqr(C.r) - sqr(dis));
  140. int ret = 0;
  141. sol[ret] = ip + dxy;
  142. if (OnSegment(sol[ret], L.p, L.point(1))) ret++;
  143. sol[ret] = ip - dxy;
  144. if (OnSegment(sol[ret], L.p, L.point(1))) ret++;
  145. return ret;
  146. }
  147.  
  148. int T, n;
  149. vector<Point> sol;
  150. Circle C[30];
  151. Point s, t;
  152. bool vis[maxn];
  153.  
  154. bool check(Point A, Point B)
  155. {
  156. vector<Point> gank;
  157. gank.PB(A);
  158. gank.PB(B);
  159. Point roshan[2];
  160. REP(i, n)
  161. {
  162. //线段ab与所有圆的交点
  163. int m = getSegCircleIntersection(Line(A, B-A), C[i], roshan);
  164. if(m == 1) gank.PB(roshan[0]);
  165. if(m == 2) gank.PB(roshan[0]), gank.PB(roshan[1]);
  166. }
  167.  
  168. sort(gank.begin(), gank.end());
  169. int nc = gank.size();
  170.  
  171. REP(i, nc-1)
  172. {
  173. Point mid = (gank[i] + gank[i+1]) / 2.0;
  174. //重点跳过
  175. if(mid == gank[i]) continue;
  176. bool flag = 0;
  177. REP(j, n) if(InCircle(mid, C[j]))//分段中点是否被任意圆覆盖
  178. {
  179. flag = 1;
  180. break;
  181. }
  182. if(!flag) return false;
  183. }
  184. return true;
  185. }
  186.  
  187. struct Heap
  188. {
  189. double d; int u;
  190. bool operator < (const Heap& rhs) const
  191. {
  192. return dcmp(d-rhs.d) > 0;
  193. }
  194. };
  195.  
  196. struct Edge
  197. {
  198. int from, to;
  199. double dist;
  200. };
  201.  
  202. vector<Edge> edges;
  203. vector<int> G[maxn];
  204. bool done[maxn];
  205. double d[maxn];
  206.  
  207. double dij(int s, int t, int n)
  208. {
  209. priority_queue<Heap> q; q.push((Heap){0.0, s});
  210. REP(i, n) d[i] = INF; d[s] = 0.0;
  211. CLR(done, 0);
  212. while(!q.empty())
  213. {
  214. Heap x = q.top(); q.pop();
  215. int u = x.u, nc = G[u].size();
  216. if(done[u]) continue;
  217. done[u] = 1;
  218. REP(i, nc)
  219. {
  220. Edge& e = edges[G[u][i]];
  221. if(dcmp(d[e.to]-d[u]-e.dist) > 0)
  222. {
  223. d[e.to] = d[u] + e.dist;
  224. q.push((Heap){d[e.to], e.to});
  225. }
  226. }
  227. }
  228. return d[t];
  229. }
  230.  
  231. void add(int from, int to, double dist)
  232. {
  233. edges.PB((Edge){from, to, dist});
  234. edges.PB((Edge){to, from, dist});
  235. int nc = edges.size();
  236. G[from].PB(nc-2);
  237. G[to].PB(nc-1);
  238. }
  239.  
  240. void init()
  241. {
  242. REP(i, maxn) G[i].clear();
  243. sol.clear();
  244. edges.clear();
  245. }
  246.  
  247. int main()
  248. {
  249. scanf("%d", &T);
  250. FF(kase, 1, T+1)
  251. {
  252. init();
  253. scanf("%d", &n);
  254. //sol存平面上所有点
  255. REP(i, n)
  256. {
  257. scanf("%lf%lf%lf", &C[i].c.x, &C[i].c.y, &C[i].r);
  258. if(i == 0 || i == n-1)
  259. sol.PB(C[i].c);//加入圆心....
  260. }
  261. REP(i, n) FF(j, i+1, n)
  262. getCCintersection(C[i], C[j], sol);//所有圆的交点
  263.  
  264. //去重
  265. sort(sol.begin(), sol.end());
  266. int nc = unique(sol.begin(), sol.end()) - sol.begin();
  267.  
  268. int s, t;
  269. REP(i, nc)
  270. {
  271. FF(j, i+1, nc) if(check(sol[i], sol[j]))
  272. //判断两点是否连通
  273. add(i, j, Length(sol[i] - sol[j]));
  274. //最短路的起始点
  275. if(sol[i] == C[0].c) s = i;
  276. if(sol[i] == C[n-1].c) t = i;
  277. }
  278.  
  279. double ans = dij(s, t, nc);
  280. printf("Case %d: ", kase);
  281. if(dcmp(ans-INF) >= 0) puts("No such path.");
  282. else printf("%.4lf\n", ans);
  283. }
  284. return 0;
  285. }

hdu 4063 Aircraft(计算几何+最短路)的更多相关文章

  1. HDU 4063 Aircraft(计算几何)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4063 Description You are playing a flying game. In th ...

  2. HDU 4063 Aircraft --几何,最短路

    题意: 给一些圆,要求从第一个圆的圆心走到最后一个圆的圆心,中间路径必须在某个圆内,求最短路径的长度. 解法: 易知要保持在圆内且路径最短,走两圆相交的点能使路径尽量短,所以我们找出所有的两圆相交的点 ...

  3. hdu 4063 Aircraft (Geometry + SP)

    Problem - 4063 几何加简单最短路. 题意是给出若干圆的圆心以及半径,求出从给出的起点到终点的最短路径的长度,可以移动的区域是圆覆盖到的任意一个位置. 做法是这样的,对圆两两求交点,用这些 ...

  4. HDU 4998 Rotate (计算几何)

    HDU 4998 Rotate (计算几何) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4998 Description Noting is more ...

  5. hdu 4643 GSM 计算几何 - 点线关系

    /* hdu 4643 GSM 计算几何 - 点线关系 N个城市,任意两个城市之间都有沿他们之间直线的铁路 M个基站 问从城市A到城市B需要切换几次基站 当从基站a切换到基站b时,切换的地点就是ab的 ...

  6. HDU 4606 Occupy Cities (计算几何+最短路+最小路径覆盖)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题目:给出n个城市需要去占领,有m条线段是障碍物, ...

  7. HDU 4063 线段与圆相交+最短路

    Aircraft Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  8. HDU 4606 Occupy Cities (计算几何+最短路+二分+最小路径覆盖)

    Occupy Cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  9. HDU 5294 Tricks Device 最短路+最大流

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5294 题意: 给你个无向图: 1.求最少删除几条边就能破坏节点1到节点n的最短路径, 2.最多能删除 ...

随机推荐

  1. Azure 网站的新增功能:可配置的环境变量

     编辑人员注释:本文章由 WindowsAzure 网站团队的项目经理Erez Benari撰写. Azure最常用的强大功能之一是 XML文档转换 (XDT),通过此功能,您可以在Windows ...

  2. srm 534

    250 Description 给你一个1*n的棋盘.两人轮流行动,每一个人能够把"o"向右移动到空格子.或者跨越连续两个"o"到空格子. 一个"o& ...

  3. RGB与HSB之间的转换公式

    先来了解一些概念: 1.RGB是一种加色模型,就是将不同比例的Red/Green/Blue混合在一起得到新颜色.通常RGB颜色模型表示为: 2.HSB(HSV) 通过色相/饱和度/亮度三要素来表达颜色 ...

  4. python 面试相关

    python单例模式: Python真的需要单例模式吗?我指像其他编程语言中的单例模式. 答案是:不需要!  因为,Python有模块(module),最pythonic的单例典范.模块在在一个应用程 ...

  5. 在CheckBox中,仅仅允许选择一项

    作用相当于RadioButonList <html xmlns="http://www.w3.org/1999/xhtml"> <head runat=" ...

  6. md5 加密 swfit版

    在swift工程中随便建一个objective-c类,会提示你生成一个Bridging-Header,点YES,然后删除刚才建立的objective-c类,只留下[工程名]-Bridging-Head ...

  7. Java学习之位运算和逻辑运算符

    今天看了一下HashMap类的源码,在HashMap的源码中定义了初始空间的大小 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; 当 ...

  8. Vmware中Ubuntu挂ISO到虚拟光驱

    Ubuntu 下挂ISO到虚拟光驱的方法 https://i.cnblogs.com/EditPosts.aspx?opt=1 如果要ubuntu找到rpm软件包,需要把iso挂载到/media/cd ...

  9. CSS3框架!

    http://usablica.github.io/front-end-frameworks/compare.html?v=2.0

  10. php实现分页,上一页下一页

    首先学东西  要多看手册用php自带的函数  可以解决一些难解的问题 <?php /**  * Created by JetBrains PhpStorm.  * User: Administr ...