社区讨论
最后一个点wa,不是精度问题,求调
P3493[POI 2009] WSP-Island参与者 2已保存回复 9
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 9 条
- 当前快照
- 1 份
- 快照标识符
- @lo34neat
- 此快照首次捕获于
- 2023/10/24 00:43 2 年前
- 此快照最后确认于
- 2023/10/24 00:43 2 年前
CPP
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define x first
#define y second
using namespace std;
typedef pair<double,double> PDD;
const double eps=1e-12;
const int N=1000005;
int n,m,cnt,idx,top;
struct Line{
PDD st,ed;
}line[N];
struct node{
int to,next;
}seg[N];
bool vis[N];
PDD p[N],ans[N];
int head[N],stac[N];
void add(int u,int v)
{
seg[++idx].to=v;
seg[idx].next=head[u];
head[u]=idx;
}
int sign(double x)
{
if(fabs(x)<eps)return 0;
if(x<0)return -1;
return 1;
}
int dcmp(double x,double y)
{
if(fabs(x-y)<eps)return 0;
if(x<y)return -1;
return 1;
}
PDD operator + (PDD a,PDD b){return {a.x+b.x,a.y+b.y};}
PDD operator - (PDD a,PDD b){return {a.x-b.x,a.y-b.y};}
PDD operator * (PDD a,double t){return {a.x*t,a.y*t};}
PDD operator / (PDD a,double t){return {a.x/t,a.y/t};}
double operator * (PDD a,PDD b){return a.x*b.y-a.y*b.x;}
double operator & (PDD a,PDD b){return a.x*b.x+a.y*b.y;}
double get_angle(Line a){return atan2(a.ed.y-a.st.y,a.ed.x-a.st.x);}
double get_dist(PDD a,PDD b)
{
PDD c=b-a;
return sqrt(c&c);
}
double area(PDD a,PDD b,PDD c){return (b-a)*(b-c);}
PDD get_line_intersection(PDD p,PDD v,PDD q,PDD w)
{
PDD u=p-q;
double t=w*u/(v*w);
return p+v*t;
}
PDD get_line_intersection(Line a,Line b){return get_line_intersection(a.st,a.ed-a.st,b.st,b.ed-b.st);}
bool setment_intersection(PDD a1,PDD a2,PDD b1,PDD b2)
{
double c1=(a2-a1)*(b1-a1),c2=(a2-a1)*(b2-b1);
double c3=(b2-b1)*(a1-b1),c4=(b2-b1)*(a2-b1);
return sign(c1*c2)<=0&&sign(c3*c4)<=0;
}
bool on_right(Line a,Line b,Line c)
{
PDD o=get_line_intersection(b,c);
return sign(area(a.st,a.ed,o))<=0;
}
//void print(Line a)
//{
// cout<<a.st.x<<" "<<a.st.y<<" "<<a.ed.x<<" "<<a.ed.y<<endl;
//}
double half_plane_intersection()
{
for(int i=1;i<=cnt;i++)
{
if(top>1&&!setment_intersection(line[stac[top]].st,line[stac[top]].ed,line[i].st,line[i].ed))continue;
if(line[stac[top]].ed==line[i].ed)continue;
while(top>1&&on_right(line[i],line[stac[top-1]],line[stac[top]]))top--;
stac[++top]=i;
}
int now=0;
double res=0;
ans[now++]=p[1];
for(int i=1;i<top;i++)
{
ans[now++]=get_line_intersection(line[stac[i]],line[stac[i+1]]);
// cout<<" --- "<<i<<" --- "<<stac[i]<<endl;
// print(line[stac[i]]);
// print(line[stac[i+1]]);
// cout<<"--------------------------------------"<<endl;
}
// cout<<" --- "<<top<<" --- "<<stac[top]<<endl;
ans[now++]=p[n];
for(int i=1;i<now;i++)
{
// printf("%.3lf %.3lf\n",ans[i].x,ans[i].y);
res+=get_dist(ans[i-1],ans[i]);
}
return res;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1,a,b;i<=n;i++)
{
scanf("%d%d",&a,&b);
p[i]={a,b};
}
for(int i=1,u,v;i<=m;i++)
{
scanf("%d%d",&u,&v);
if(u>v)swap(u,v);
add(u,v);
}
for(int i=1;i<n;i++)
{
bool ok;
for(int j=head[i],v;j;j=seg[j].next)
{
v=seg[j].to;
vis[v]=true;
}
for(int k=n;k>i;k--)
{
if(vis[k])continue;
line[++cnt].st=p[i];
line[cnt].ed=p[k];
break;
}
for(int j=head[i],v;j;j=seg[j].next)
{
v=seg[j].to;
vis[v]=false;
}
}
double res;
res=half_plane_intersection();
printf("%.10lf",res);
return 0;
}
回复
共 9 条回复,欢迎继续交流。
正在加载回复...