BZOJ1137:[POI2009]Wsp 岛屿(半平面交)
来源:互联网 发布:中秋节数据 编辑:程序博客网 时间:2024/05/17 23:22
传送门
Byteotia岛屿是一个凸多边形。城市全都在海岸上。按顺时针编号1到n。任意两个城市之间都有一条笔直的道路相连。道路相交处可以自由穿行。有一些道路被游击队控制了,不能走,但是可以经过这条道路与未被控制的道路的交点。问从城市1到n的最短距离。
题解:
首先凸多边形中1到n的最短路可以用半平面交做,发现一个点出发的直线只有可能是最后一条在半平面交中存在,所以用最后一条直接做半平面交就好了。
#include<bits/stdc++.h>using namespace std;inline int read(){ char ch=getchar();int i=0,f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=getchar();} return i*f;}const int Maxn=1e5+50;const double eps=1e-9;inline int sgn(double x){return (x>eps)-(x<-eps);}struct point{ double x,y; point(){} point(double x,double y):x(x),y(y){} friend inline point operator -(const point &a,const point &b){return point(a.x-b.x,a.y-b.y);} friend inline double operator *(const point &a,const point &b){return a.x*b.y-a.y*b.x;} inline double norm(){return sqrt(x*x+y*y);}}p[Maxn];struct line{ point a,b; double sp; line(){} line(point a,point b):a(a),b(b){}}l[Maxn];int n,m,tot;vector<int>ban[Maxn];inline bool operator <(const line &a,const line &b){ int t=sgn(a.sp-b.sp); if(t)return t<0; else return (b.b-a.a)*(b.a-a.a)>=0;}inline point insert(const line &a,const line &b){ double k1=(a.b-b.a)*(a.a-b.a); double k2=(a.a-b.b)*(a.b-b.b); #define t k1/(k1+k2) return point(b.a.x+(b.b.x-b.a.x)*t,b.a.y+(b.b.y-b.a.y)*t); #undef t}inline bool judge(const line &c,const line &a,const line &b){ point q=insert(a,b); return (c.a-q)*(c.b-q)<eps; }inline void hpi(){ for(int i=1;i<=tot;i++)l[i].sp=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x); sort(l+1,l+tot+1);m=0; for(int i=1;i<=tot;i++){ if(i==1||sgn(l[i].sp-l[i-1].sp))++m; l[m]=l[i]; } int L=1,R=2; for(int i=3;i<=m;i++){ while(L<R&&judge(l[i],l[R-1],l[R]))--R; while(L<R&&judge(l[i],l[L],l[L+1]))++L; l[++R]=l[i]; } while(L<R-1&&judge(l[R],l[L],l[L+1]))++L; while(L<R-1&&judge(l[L],l[R-1],l[R]))--R; double ans=-(p[n]-p[1]).norm();tot=0;l[++R]=l[L]; for(int i=L;i<R;++i)p[++tot]=insert(l[i],l[i+1]); for(int i=1;i<tot;i++)ans+=(p[i+1]-p[i]).norm(); ans+=(p[1]-p[tot]).norm(); printf("%.10f\n",ans); }int main(){ n=read(),m=read(); for(int i=1;i<=n;i++)p[i].x=read(),p[i].y=read(); for(int i=1;i<=m;i++){ int x=read(),y=read(); ban[min(x,y)].push_back(max(x,y)); } for(int i=1;i<=n;i++){ if(ban[i].size())sort(ban[i].begin(),ban[i].end()); int t=ban[i].size()-1,o=n; while(t>=0&&ban[i][t]==o)--o,--t; if(o>i)l[++tot]=line(p[o],p[i]); }l[++tot]=line(p[1],p[n]); hpi();}
阅读全文
0 0
- bzoj1137 [POI2009]Wsp 岛屿 半平面交
- [BZOJ1137][POI2009]Wsp 岛屿(半平面交)
- BZOJ1137:[POI2009]Wsp 岛屿(半平面交)
- bzoj 1137: [POI2009]Wsp 岛屿 (半平面交)
- bzoj1137【POI2009】Wsp 岛屿
- BZOJ1137: [POI2009]Wsp 岛屿
- BZOJ1137: [POI2009]Wsp 岛屿
- BZOJ 1137 POI2009 Wsp 岛屿 半平面交
- 半平面交(未完成)
- poj1474(半平面交)
- poj3335(半平面交)
- BZOJ2618 (半平面交)
- 半平面交(入门)
- bzoj-1137 Wsp 岛屿
- URAL 1062 - Triathlon(半平面交)
- POJ3525(二分+半平面交)
- POJ2540-Hotter Colder(半平面交)
- poj 3335(半平面交)
- Android中关于图片的一些操作
- mysql自动备份
- 不服来战,看Kotlin如何完爆Java
- 万树IT:Java概述与基本语法
- 大道至简
- BZOJ1137:[POI2009]Wsp 岛屿(半平面交)
- Python之mysql删改优化
- 用powershell登录网站,获取登录后的response,再对response进行字符串的截取
- Linux中环境变量文件及配置
- 语音合成技术
- Bailian2730 求20以内n的阶乘【递推】(Bailian2729 求12以内n的阶乘)
- Android官方ORM数据库Room技术解决方案:@Embedded内嵌对象(二)
- VGG-阅读笔记-理解
- Java8 Stream篇章