luogu4196 [CQOI2006]凸多边形 半平面交

据说pkusc出了好几年半平面交了,我也来水一发
ref

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n, cnt, tot;
const double eps=1e-7;
struct Point{
	double x, y;
	Point(double u=0.0, double v=0.0){
		x = u; y = v;
	}
	Point operator+(const Point &u)const{
		return Point(x+u.x, y+u.y);
	}
	Point operator-(const Point &u)const{
		return Point(x-u.x, y-u.y);
	}
	double crs(Point u){
		return x*u.y-y*u.x;
	}
}pt[55], a[1005];
struct Line{
	Point x, y;
	double ang;
	Line(){}
	Line(Point u, Point v){
		x = u; y = v;
		ang = atan2(v.y-u.y, v.x-u.x);
	}
}l[1005], d[1005];
Point operator*(double x, Point u){
	return Point(x*u.x, x*u.y);
}
bool cmp(Line u, Line v){
	if(fabs(u.ang-v.ang)>=eps)	return u.ang<v.ang;
	return (u.y-u.x).crs(v.y-u.x)>eps;
}
Point inter(Line u, Line v){
	double t=(v.x-u.x).crs(v.y-u.x)/((v.x-u.x).crs(v.y-u.x)+(v.y-u.y).crs(v.x-u.y));
	return u.x+t*(u.y-u.x);
}
bool isLeft(Point u, Line v){
	return (v.y-v.x).crs(u-v.x)>eps;
}
void halfPlaneIntersection(){
	sort(l+1, l+1+cnt, cmp);
	for(int i=1; i<=cnt; i++){
		if(i==1 || fabs(l[i].ang-l[i-1].ang)>=eps)	tot++;
		l[tot] = l[i];
	}
	cnt = tot; tot = 0;
	int ll=1, rr=0;
	d[++rr] = l[1]; d[++rr] = l[2];
	for(int i=3; i<=cnt; i++){
		while(ll<rr && !isLeft(inter(d[rr-1], d[rr]), l[i]))	rr--;
		while(ll<rr && !isLeft(inter(d[ll+1], d[ll]), l[i]))	ll++;
		d[++rr] = l[i];
	}
	while(ll<rr && !isLeft(inter(d[rr-1], d[rr]), d[ll]))	rr--;
	while(ll<rr && !isLeft(inter(d[ll+1], d[ll]), d[rr]))	ll++;
	d[rr+1] = d[ll];
	for(int i=ll; i<=rr; i++)
		a[++tot] = inter(d[i], d[i+1]);
}
double ans(){
	if(tot<3)	return 0.0;
	a[tot+1] = a[1];
	double re=0;
	for(int i=1; i<=tot; i++)
		re += a[i].crs(a[i+1]);
	return re/2;
}
int main(){
	cin>>n;
	while(n--){
		int mi;
		scanf("%d", &mi);
		for(int i=1; i<=mi; i++)
			scanf("%lf %lf", &pt[i].x, &pt[i].y);
		pt[mi+1] = pt[1];
		for(int i=1; i<=mi; i++)
			l[++cnt] = (Line){pt[i], pt[i+1]};
	}
	halfPlaneIntersection();
	printf("%.3f\n", ans());
	return 0;
}
posted @ 2018-05-28 08:56  poorpool  阅读(103)  评论(0编辑  收藏  举报