bzoj 1137 [POI2009]Wsp 岛屿
题目大意
Byteotia岛屿是一个凸多边形。城市全都在海岸上。按顺时针编号1到n。任意两个城市之间都有一条笔直的道路相连。道路相交处可以自由穿行。有一些道路被游击队控制了,不能走,但是可以经过这条道路与未被控制的道路的交点。问从城市1到n的最短距离。
两条道路相交的话,可以从一条道路出发,走到交点直接转弯走!
两条道路相交的话,可以从一条道路出发,走到交点直接转弯走!
两条道路相交的话,可以从一条道路出发,走到交点直接转弯走!
分析
因为编号是顺时针编号的
所以我们最优一定会选择编号最大的点去走
(记这条边为L
如果走到一个编号较小的点
最终目标还是要走到n
最后会穿过L这条边
与L相交于D
那还不如我走L这条边走到D这个点转弯呢
)
这样剩下的边数就从\(O(n^2)\)变成\(O(n)\)了
可以发现最短路是半平面交
注意
1.被控制的边有重边
2.找最大可走编号点时注意边界
3.注意半平面交退化的特殊情况要特判
solution
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef double db;
const int M=100007;
inline int rd(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
}
int n,m;
struct pt{
db x,y;
pt(db xx=0,db yy=0){x=xx;y=yy;}
}p[M],a[M];
int tot;
pt operator +(pt x,pt y){return pt(x.x+y.x,x.y+y.y);}
pt operator -(pt x,pt y){return pt(x.x-y.x,x.y-y.y);}
pt operator *(pt x,db d){return pt(x.x*d,x.y*d);}
pt operator /(pt x,db d){return pt(x.x/d,x.y/d);}
db dot(pt x,pt y){return x.x*y.x+x.y*y.y;}
db det(pt x,pt y){return x.x*y.y-x.y*y.x;}
db len(pt x){return sqrt(dot(x,x));}
db dis(pt x,pt y){return len(y-x);}
db area(pt x,pt y,pt z){return det(y-x,z-x);}
struct line{
pt P,v;
line(pt PP=pt(),pt vv=pt()){P=PP;v=vv;}
}l[M],s[M];
int cnt,top;
bool ptleft(pt x,line y){return det(y.v,x-y.P)>=0;}
pt inter(line x,line y){
pt u=x.P-y.P;
db t=det(u,y.v)/det(y.v,x.v);
return x.P+x.v*t;
}
vector<int>g[M];
bool cc(int x,int y){return x>y;}
void hpi(){
top=0;
int i;
for(i=1;i<=cnt;i++){
while(top>1&&ptleft(inter(s[top-1],s[top]),l[i])) top--;
s[++top]=l[i];
}
tot=0;
for(i=2;i<=top;i++) a[++tot]=inter(s[i],s[i-1]);
}
int main(){
int i,j,x,y;
n=rd(),m=rd();
for(i=1;i<=n;i++){
x=rd(),y=rd();
p[i]=pt(x,y);
g[i].push_back(0);//防止下面遍历到最后都找不到边
}
for(i=1;i<=m;i++){
x=rd(),y=rd();
if(x>y) swap(x,y);
g[x].push_back(y);
}
for(i=1;i<n;i++) sort(g[i].begin(),g[i].end(),cc);
int mx=0;
for(i=1;i<n;i++){
int lst=n;
for(j=0;j<g[i].size();j++){
if(lst<=mx) break;
if(g[i][j]==lst){
for(;j<g[i].size()&&g[i][j]==lst;j++);
lst--; j--;
}
else{
mx=lst;
l[++cnt]=line(p[i],p[mx]-p[i]);
break;
}
}
}
hpi();
if(tot==0){
printf("%.10lf\n",dis(p[1],p[n]));
return 0;
}
db ans=0;
ans+=dis(p[1],a[1]);
for(i=2;i<=tot;i++) ans+=dis(a[i-1],a[i]);
ans+=dis(a[tot],p[n]);
printf("%.10lf\n",ans);
return 0;
}
bzoj 1137 [POI2009]Wsp 岛屿的更多相关文章
- BZOJ 1137: [POI2009]Wsp 岛屿 半平面交
1137: [POI2009]Wsp 岛屿 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 165 Solved: ...
- [BZOJ 1135][POI2009]Lyz
[BZOJ 1135][POI2009]Lyz 题意 初始时滑冰俱乐部有 \(1\) 到 \(n\) 号的溜冰鞋各 \(k\) 双.已知 \(x\) 号脚的人可以穿 \(x\) 到 \(x+d\) 的 ...
- BZOJ 1115: [POI2009]石子游戏Kam
1115: [POI2009]石子游戏Kam Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 883 Solved: 545[Submit][Stat ...
- BZOJ 1142: [POI2009]Tab
1142: [POI2009]Tab Time Limit: 40 Sec Memory Limit: 162 MBSubmit: 213 Solved: 80[Submit][Status][D ...
- bzoj 1133: [POI2009]Kon dp
1133: [POI2009]Kon Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 242 Solved: 81[Submit][Status][D ...
- bzoj 1138: [POI2009]Baj 最短回文路 dp优化
1138: [POI2009]Baj 最短回文路 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 161 Solved: 48[Submit][Sta ...
- [BZOJ 1115] [POI2009] 石子游戏Kam 【阶梯博弈】
题目链接:BZOJ - 1115 题目分析 首先看一下阶梯博弈: 阶梯博弈是指:初始有 n 堆石子,每次可以从任意的第 i 堆拿若干石子放到第 i - 1 堆.最终不能操作的人失败. 解法:将奇数位的 ...
- BZOJ 1119: [POI2009]SLO [置换群]
传送门:现在$POI$上的题洛谷都有了,还要$BZOJ$干什么 和$cow\ sorting$一样,只不过问$a_i \rightarrow b_i$ 注意置换是位置而不是数值...也就是说要$i$的 ...
- BZOJ.1115.[POI2009]石子游戏Kam(阶梯博弈)
BZOJ 洛谷 \(Description\) 有\(n\)堆石子.除了第一堆外,每堆石子个数都不少于前一堆的石子个数.两人轮流操作,每次可以从一堆石子中拿掉任意多的石子,但要保证操作后仍然满足初始时 ...
随机推荐
- Hibernate异常:identifier of an instance of 错误
今天写项目时,在使用hibernate封装的插入方法时,由于需要同时保存多个数据,导致出现identifier of an instance of 如下代码 :(由于最大最小分数不同所以需要插入两条数 ...
- RabbitMQ 学习资料
https://www.rabbitmq.com/getstarted.html http://www.cnblogs.com/luxiaoxun/p/3918054.html http://back ...
- Bootstrap历练实例:激活导航状态
激活导航状态 您可以在激活状态的胶囊式导航和列表导航中放置徽章.通过使用 <span class="badge"> 来激活链接,如下面的实例所示: <!DOCTY ...
- iOS动画之iOS UIBezierPath类 介绍
感谢:http://blog.csdn.net/crayondeng/article/details/11093689 使用UIBezierPath类可以创建基于矢量的路径,这个类在UIKit中.此类 ...
- C# 用qq邮箱发邮件
一.在企业的QQ邮箱中开启POP3/SMTP服务 开启服务时,授权密码保存好. 二.示例 public static string UserName = ""; // 企业邮箱 p ...
- 解决Windows 与Mac 双系统下的蓝牙设备共用的问题
不知道有多少人和我一样用的蓝牙鼠标或者键盘,有的话应该都会遇到同一个问题:即在一个系统下配好对后在另一个系统必须重新配对才能使用,很是麻烦.还要将蓝牙设备进入发现模式,OS下搜索,连接....终于昨天 ...
- 2829: 高精A+B [1*+]
题目描述 输入A和B,计算A+B的值 Input 两行数据,分别是A和B 0<=A<=1E200 0<=B<=10^200 Output A+B的结果 Sample Input ...
- C#基础-数组-冒泡排序
冒泡排序基础 冒泡排序原理图分析 tmp在算法中起到数据交换的作用 int[] intNums = { 12,6,9,3,8,7 }; int tmp = intNums[0]; // 一共5次冒泡, ...
- 使用slot-scope复制vue中slot内容
有时候我们的vue组件需要复制使用者传递的内容. 比如我们工程里面的轮播组件需要使用复制的slot来达到循环滚动的效果 使用者关注轮播内容的静态效果,组件负责让其滚动起来 组件: <div cl ...
- ipvsadm分发MySQL读请求
在MySQL的部署场景中,经常使用HAproxy和ipvs来作为读请求转发的网关.ipvs的好处在于本身不需要daemon的方式来运行,而是直接作为kernel的服务来提供:当ipvs和应用程序服务器 ...