UOJ #277 BZOJ 4739 [清华集训2016]定向越野 (计算几何、最短路)

手动博客搬家: 本文发表于20181208 14:39:01, 原地址https://blog.csdn.net/suncongbo/article/details/84891710

哇它居然显示出图片来了……感动啊

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4739http://uoj.ac/problem/277

不难得出一个结论: 两圆之间最短路一定沿着圆的公切线走。然后得到如下算法:每两个圆之间作公切线(4条),如果一条公切线不穿过其他圆,就把这两个点(图论中的点)之间连上边,边权为切线长;同一圆上相邻两点连边,边权为圆上距离,然后S,T分别向每个圆作切线如果不和其他圆相交就连边。这样的话点数、边数是\(O(n^2)\)级别的,使用Dijkstra算法求最短路即可。时间复杂度瓶颈在于对于一条边枚举每一个圆去check是否相交,总时间复杂度\(O(n^3)\). 奇迹般地能跑过。
下面重点讲解一下我是如何求两圆公切线以及点和圆的切线的:
先来说两圆公切线:因为两圆外离所以一定有\(4\)条公切线,\(2\)\(2\)外。
考虑先把圆按半径从大到小排序,现在要从半径大的圆向半径小的圆作\(4\)条切线。
设两圆圆心(已知)分别为\(O_1, O_2\), 圆心的直线距离\(O_1O_2=d\), 半径分别为\(r_1r_2\), 一条外公切线为\(AB\)(未知)。
\(O_2\)\(O_2E\perp AO_1\)\(D\), 则\(AEO_2B\)为矩形。\(AE=BO_2=r_2\), \(EO_1=AO_1-AE=r_1-r_2\), 又\(O_1E\perp O_2E\), 可用勾股定理算出切线长\(AB=EO_2=\sqrt{d^2-(r_1-r_2)^2}\). 同时有\(\cos \angle EO_1O_2=\frac{r_1-r_2}{d}\), 可利用acos函数算出\(\angle EO_1O_2\)的值。然后求出向量\(\vec {OA}=\frac{r_1}{d}\vec v\)即可,其中\(\vec v\)\(\vec {O_1O_2}\)逆时针旋转\(\angle EO_1O_2\)的向量。


另外一条外公切线同理,把旋转度数取反即可。
代码如下:
Line tmp; double d = EuclidDist(a[i].o,a[j].o); Vector v; double ang; Point p1,p2;
   //Out 1
   ang = acos((a[i].r-a[j].r)/d); v = rotate(Vector(a[j].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值