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

6 9
-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

42.000000000

HINT

 

Source

 
先瞎BB几句,习惯不看背景的我,一眼看过去以为是求补图的最短路。论审题的重要性。
想法:
根据“道路相交处可以自由穿行。”,然后画图发现。可以把所有合法的路拿出来,把包含1,n的那面作为合法面。这样做一遍半平面交,得到凸多边形的周长就是答案。O(n^2logn)
然后根据“XXX岛屿是一个凸多边形。”,距离最短的合法路肯定是终点编号大的。所以每个点最多只要取一条路就好了。O(nlogn)
 
#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 岛屿 半平面交的更多相关文章

  1. bzoj 1137 [POI2009]Wsp 岛屿

    题目大意 Byteotia岛屿是一个凸多边形.城市全都在海岸上.按顺时针编号1到n.任意两个城市之间都有一条笔直的道路相连.道路相交处可以自由穿行.有一些道路被游击队控制了,不能走,但是可以经过这条道 ...

  2. BZOJ 1038 ZJOI2008 瞭望塔 半平面交

    题目大意及模拟退火题解:见 http://blog.csdn.net/popoqqq/article/details/39340759 这次用半平面交写了一遍--求出半平面交之后.枚举原图和半平面交的 ...

  3. bzoj 4445 小凸想跑步 - 半平面交

    题目传送门 vjudge的快速通道 bzoj的快速通道 题目大意 问在一个凸多边形内找一个点,连接这个点和所有顶点,使得与0号顶点,1号顶点构成的三角形是最小的概率. 假设点的位置是$(x, y)$, ...

  4. bzoj 3190 赛车 半平面交

    直接写的裸的半平面交,已经有点背不过模板了... 这题卡精度,要用long double ,esp设1e-20... #include<iostream> #include<cstd ...

  5. BZOJ 4445 [Scoi2015]小凸想跑步:半平面交

    传送门 题意 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 $ n $ 边形,$ n $ 个顶点 $ P_i $ 按照逆时针从 $ 0 $ 至 $ n-1 $ 编号. ...

  6. BZOJ 1829 [Usaco2010 Mar]starc星际争霸 ——半平面交

    发现最终的结果只和$s1$,$s2$,$s3$之间的比例有关. 所以直接令$s3=1$ 然后就变成了两个变量,然后求一次半平面交. 对于每一个询问所属的直线,看看半平面在它的那一侧,或者相交就可以判断 ...

  7. 【BZOJ-4515】游戏 李超线段树 + 树链剖分 + 半平面交

    4515: [Sdoi2016]游戏 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 304  Solved: 129[Submit][Status][ ...

  8. poj3335 半平面交

    题意:给出一多边形.判断多边形是否存在一点,使得多边形边界上的所有点都能看见该点. sol:在纸上随手画画就可以找出规律:按逆时针顺序连接所有点.然后找出这些line的半平面交. 题中给出的点已经按顺 ...

  9. POJ3525 半平面交

    题意:求某凸多边形内部离边界最远的点到边界的距离 首先介绍半平面.半平面交的概念: 半平面:对于一条有向直线,它的方向的左手侧就是它所划定的半平面范围.如图所示: 半平面交:多个半平面的交集.有点类似 ...

随机推荐

  1. eclipse中jquery.js文件有错误提示…

    eclipse中jquery.js文件有错误提示的解决办法 2013-04-06 19:18 浏览次数:382 由于jquery.js文件进行了压缩,压缩之后的语法eclipse无法完全识别,所以有错 ...

  2. (一)新建一个javaweb项目

    一.为了不影响其他项目,可以重新选择一个新的工作目录:swith workspace 二.为了尽可能统一项目,所使用的编程环境,包括:Tomcat.JRE都是项目组自己的,所以在新建项目的时候要注意选 ...

  3. 利用html5看雪花飘落的效果

    html5飘落的雪花堆积动画特效 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-T ...

  4. VS2017 不能创建 vsto Excel 工作簿程序的问题

    最近想写个小程序,是基于vsto的excel 扩展程序. 打开vs2017,创建时,却提示 不能创建项目(创建项目失败,Project cannot be created).原本以为很顺利的,不相处了 ...

  5. MySQL写入中文乱码

    这点确实很迷,我的数据库属性确实设置了utf-8字符集,但写入中文还是乱码,后来是直接修改了全局配置才修改过来. 1.进入MySQL的本地安装路径,我的安装路径是"C:\Program Fi ...

  6. c++中调用python脚本提示 error LNK2001: 无法解析的外部符号 __imp_Py_Initialize等错误的解决方法

    最近项目中需要实现一个服务器宕机后短信提醒的功能,个人觉得在使用Python 写http请求这块很方便,发短信这块就使用了python,但是c++程序中调用这个脚本时,编译不通过,提示如下错误: er ...

  7. MYSQL limit,offset 区别(转)

    SELECT keyword FROM keyword_rank WHERE advertiserid='59' order by keyword LIMIT 2 OFFSET 1; 比如这个SQL ...

  8. 自动化测试工具 Test Studio入门教程

    Test Studio安装 可以到下载试用版 官网 http://www.telerik.com/teststudio , 装完以后需要装silverlight 安装好了,主界面是介个样子的 Test ...

  9. 2017-9-20 NOIP模拟赛

    A 约数之和 (count.pas/c/cpp)TL:1S ML:128MB[Description]我们用 D(x)表示正整数 x 的约数的个数.给定一个正整数 N,求 D(1)+D(2)+…+D( ...

  10. MySQL (case when then else end)和常用函数用法

    case when then else end 相当于Java的if-else if-else,可以用来在select语句中将要显示的内容替换成另一个内容 更多用法:https://www.cnblo ...