BZOJ 1137: [POI2009]Wsp 岛屿 半平面交
1137: [POI2009]Wsp 岛屿
Time Limit: 10 Sec Memory Limit: 162 MBSec Special Judge
Submit: 165 Solved: 78
[Submit][Status][Discuss]
Description
Byteotia岛屿是一个凸多边形。城市全都在海岸上。按顺时针编号1到n。任意两个城市之间都有一条笔直的道路相连。道路相交处可以自由穿行。有一些道路被游击队控制了,不能走,但是可以经过这条道路与未被控制的道路的交点。问从城市1到n的最短距离。
Input
第一行正整数n m表示城市数和被控制的岛屿数(3≤n≤10^5 1≤m≤10^6)接下来n行每行两个整数x y表示每个城市的坐标。(|x|,|y|≤10^6)接下来m行描述一条不能走的道路(起点和终点)。数据保证有解。
Output
输出一个实数,最短距离,误差10^-5以内均算正确。
Sample Input
-12 -10
-11 6
-4 12
6 14
16 6
18 -2
3 4
1 5
2 6
2 3
4 5
3 5
1 3
3 6
1 6
Sample Output
HINT
Source
#include<cmath>
#include<cstdio>
#include<vector>
#include<algorithm> const int len();
const double eps(1e-);
struct Coor//向量或点
{
double x,y;
Coor(){};
Coor(double a,double b):x(a),y(b){};
inline Coor operator +(const Coor&a)const{return Coor(x+a.x,y+a.y);}
inline Coor operator -(const Coor&a)const{return Coor(x-a.x,y-a.y);}
inline Coor operator *(const double&k)const{return Coor(x*k,y*k);}
inline Coor operator /(const double&k)const{return Coor(x/k,y/k);}
}pr[len+],ie[len+];int tot;
double dot(Coor a,Coor b){return a.x*b.x+a.y*b.y;}//点积
double cross(Coor a,Coor b){return a.x*b.y-a.y*b.x;}//叉积
struct Line
{
Coor a,b;//直线上两个点a->b,钦点半平面交均保留向量左手方向。
double angle;
Line(){};
Line(Coor A,Coor B,double a):a(A),b(B),angle(a){};
Coor intersect(Line &B)
{
double s1=cross(B.a-a,B.b-a),s2=cross(B.b-b,B.a-b);//面积的方向
return a+(b-a)*s1/(s1+s2);
}
void getAngle(){angle=atan2(b.y-a.y,b.x-a.x);}
}L[len+];int up;
int n,m,x,y;long double ans;
std::vector<int>Edge[len+];
void swap(int &x,int &y){x^=y,y^=x,x^=y;}
int dcmp(double x){return x<-eps?-:x>eps;}
bool cmp(Line A,Line B)
{
double c=A.angle-B.angle;
int d=dcmp(c);
if(d)return d>;//逆时针,事实证明这里正着反着都一样。
c=cross(A.b-A.a,B.b-A.a);//保留左手方向
return c<-eps;
}
bool jud(Line p1,Line p2,Line p3)
{
Coor p=p1.intersect(p2);
double c=cross(p3.b-p3.a,p-p3.a);
return dcmp(c)<;
}
void deal()
{
int _up=;
for(int i=;i<=up;i++)if(dcmp(L[i-].angle-L[i].angle))L[++_up]=L[i];
up=_up;
}
long double sqr(long double x){return x*x;}
long double dis(Coor A,Coor B)
{
return sqrt(sqr(A.x-B.x)+sqr(A.y-B.y));
}
int que[len+],head,tail;
void SI()
{
std::sort(L+,L++up,cmp);//排序可能会打乱顺序
deal();
que[]=;que[]=;head=;tail=;
for(int i=;i<=up;i++)
{
while(head<tail && jud(L[que[tail-]],L[que[tail]],L[i]))
tail--;
while(head<tail && jud(L[que[head+]],L[que[head]],L[i]))
head++;
que[++tail]=i;
}
while(head<tail- && jud(L[que[tail-]],L[que[tail]],L[que[head]]))
tail--;
while(head+<tail && jud(L[que[head+]],L[que[head]],L[que[tail]]))
head++;
que[tail+]=que[head];
for(int i=head;i<=tail;i++)ie[++tot]=L[que[i]].intersect(L[que[i+]]);
ie[tot+]=ie[];
for(int i=;i<=tot;i++)ans+=dis(ie[i],ie[i+]);
ans-=dis(pr[],pr[n]);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%lf %lf",&pr[i].x,&pr[i].y);
for(int i=;i<=m;i++)
{
scanf("%d %d",&x,&y);
if(x>y)swap(x,y);
Edge[x].push_back(y);
}
for(int i=,j;i<n;i++)
{
std::sort(Edge[i].begin(),Edge[i].end());
j=n;
while(Edge[i].size()&&Edge[i].back()==j&&j>i)
j--,Edge[i].pop_back();
if(j>i)L[++up]=Line(pr[j],pr[i],);//逆时针
if(i==&&j==n)ans=dis(pr[],pr[n]);
}
if(ans){printf("%.10Lf\n",ans);return ;}
L[++up]=Line(pr[],pr[n],);
for(int i=;i<=up;i++)L[i].getAngle();
SI();
printf("%.10Lf\n",ans);
return ;
}
BZOJ 1137: [POI2009]Wsp 岛屿 半平面交的更多相关文章
- bzoj 1137 [POI2009]Wsp 岛屿
题目大意 Byteotia岛屿是一个凸多边形.城市全都在海岸上.按顺时针编号1到n.任意两个城市之间都有一条笔直的道路相连.道路相交处可以自由穿行.有一些道路被游击队控制了,不能走,但是可以经过这条道 ...
- BZOJ 1038 ZJOI2008 瞭望塔 半平面交
题目大意及模拟退火题解:见 http://blog.csdn.net/popoqqq/article/details/39340759 这次用半平面交写了一遍--求出半平面交之后.枚举原图和半平面交的 ...
- bzoj 4445 小凸想跑步 - 半平面交
题目传送门 vjudge的快速通道 bzoj的快速通道 题目大意 问在一个凸多边形内找一个点,连接这个点和所有顶点,使得与0号顶点,1号顶点构成的三角形是最小的概率. 假设点的位置是$(x, y)$, ...
- bzoj 3190 赛车 半平面交
直接写的裸的半平面交,已经有点背不过模板了... 这题卡精度,要用long double ,esp设1e-20... #include<iostream> #include<cstd ...
- BZOJ 4445 [Scoi2015]小凸想跑步:半平面交
传送门 题意 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 $ n $ 边形,$ n $ 个顶点 $ P_i $ 按照逆时针从 $ 0 $ 至 $ n-1 $ 编号. ...
- BZOJ 1829 [Usaco2010 Mar]starc星际争霸 ——半平面交
发现最终的结果只和$s1$,$s2$,$s3$之间的比例有关. 所以直接令$s3=1$ 然后就变成了两个变量,然后求一次半平面交. 对于每一个询问所属的直线,看看半平面在它的那一侧,或者相交就可以判断 ...
- 【BZOJ-4515】游戏 李超线段树 + 树链剖分 + 半平面交
4515: [Sdoi2016]游戏 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 304 Solved: 129[Submit][Status][ ...
- poj3335 半平面交
题意:给出一多边形.判断多边形是否存在一点,使得多边形边界上的所有点都能看见该点. sol:在纸上随手画画就可以找出规律:按逆时针顺序连接所有点.然后找出这些line的半平面交. 题中给出的点已经按顺 ...
- POJ3525 半平面交
题意:求某凸多边形内部离边界最远的点到边界的距离 首先介绍半平面.半平面交的概念: 半平面:对于一条有向直线,它的方向的左手侧就是它所划定的半平面范围.如图所示: 半平面交:多个半平面的交集.有点类似 ...
随机推荐
- 项目debug1
QuestionController代码如下: @RequestMapping(value = "/question/{qid}", method = {RequestMethod ...
- 远程抓取win7 的用户登录时间
protected void Page_Load(object sender, EventArgs e) { InvokeSystemPS("query user /server:192.1 ...
- HDU - 6185 Covering(暴搜+递推+矩阵快速幂)
Covering Bob's school has a big playground, boys and girls always play games here after school. To p ...
- Working Experience - MoveWindow API 失败/无效
写在前面 当然过程不可能这么顺风顺水,毕竟对 Win32 API 不熟悉,并且国内搜索引擎和博客质量较低(不误导你就算好了),最后还是通过 Google -> StackOverflow 找到答 ...
- 字符串反转reverse
我们有一串字符串,比如: DECLARE @Source VARCHAR(MAX)= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 现想把它反转显示: ZYXWVUTSRQPONMLKJI ...
- Spark HA 配置中spark.deploy.zookeeper.url 的意思
Spark HA的配置网上很多,最近我在看王林的Spark的视频,要付费的.那个人牛B吹得很大,本事应该是有的,但是有本事,不一定就是好老师.一开始吹中国第一,吹着吹着就变成世界第一.就算你真的是世界 ...
- bzoj 4788: [CERC2016]Bipartite Blanket【hall定理+状压】
考虑当前合法的一个点集s,如果他合法,那么一定有一个完备匹配的点集包含这个点集,也就是两边都满足hall定理的话这两边拼起来的点集也满足要求 所以分别状压两边点集用hall定理转移判断当前点集是否合法 ...
- 平衡的阵容 st表学习
模板 预处理 void rmq_isit() { ;i<=n;i++) mx[i][]=mn[i][]=a[i]; ;(<<j)<=n;j++) ;i+(<<j)- ...
- jzoj6003. 【THUWC2019模拟2019.1.16】Square (乱搞)
题面 题解 不难发现,如果一行最后被染色,那么这行的颜色肯定一样,如果倒数第二个被染色,那么除了被最后一个染色的覆盖的那一部分剩下的颜色肯定一样 于是题目可以转化为每一次删去一行或一列颜色相同的,问最 ...
- uoj#340. 【清华集训2017】小 Y 和恐怖的奴隶主(矩阵加速)
传送门 uoj上的数据太毒了--也可能是我人傻常数大的缘故-- 三种血量的奴隶主加起来不超过\(8\)个,可以枚举每种血量的奴隶主个数,那么总的状态数只有\(165\)种,设\(dp_{t,i,j,k ...