社区讨论

最后一个点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 条回复,欢迎继续交流。

正在加载回复...