半平面交 模板 bzoj2618 【Cqoi2006】凸多边形

来源:互联网 发布:mac flamingo 编辑:程序博客网 时间:2024/05/08 10:09

题目大意:
给两个凸多边形,求面积交。

题目分析:
求半平面交。

代码如下:

#include <cstdio>#include <algorithm>#include <cmath>using namespace std;struct point{    double x,y;    point(){}    point(double x,double y):x(x),y(y){}    point operator + (const point &c) const { return point(x+c.x,y+c.y); }    point operator - (const point &c) const { return point(x-c.x,y-c.y); }    double operator * (const point &c) const { return x*c.y-y*c.x; }    point operator * (const double &c) const { return point(x*c,y*c); }}b[1000];struct line{    point p,v;    double alpha;    bool operator < (const line &c) const{ return alpha<c.alpha; }    line(){}    line(point a,point b):p(a),v(b-a){ alpha=atan2(v.y,v.x); }    point operator ^ (const line &c) const    {        point tmp=p-c.p;        double rate=(c.v*tmp)/(v*c.v);        return p+v*rate;    }}a[1000000],p[1000000];int tot,m,n,l,r;bool onleft(point p,line l){    point tmp=p-l.p;    return l.v*tmp>=0;}void half_plane_intersection(){    sort(a+1,a+1+tot);    for(int i=1;i<=tot;i++)    {        while(r-l>=2 && !onleft(p[r-1]^p[r-2],a[i])) r--;        if(r-l>=1 && fabs(p[r-1].v*a[i].v)<=0)            p[r-1]=onleft(a[i].p,p[r-1])?a[i]:p[r-1];        else p[r++]=a[i];    }    for(;;)    {             if(r-l>=2 && !onleft(p[r-1]^p[r-2],p[l])) r--;        else if(r-l>=2 && !onleft(p[l]^p[l+1],p[r-1])) l++;        else break;    }}int main(){    scanf("%d",&m);    tot=0;    for(int j=1;j<=m;j++)    {        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            scanf("%lf%lf",&b[i].x,&b[i].y);            if(i!=1) a[++tot]=line(b[i-1],b[i]);        }        a[++tot]=line(b[n],b[1]);    }    half_plane_intersection();    if(r-l<=2) printf("0.000\n");    else    {        int sum=0;        for(int i=l+1;i<r;i++) b[++sum]=p[i-1]^p[i];        b[++sum]=p[r-1]^p[l];        double ans=0;        for(int i=2;i<=sum;i++) ans+=b[i-1]*b[i];        ans+=b[sum]*b[1];        printf("%.3lf\n",ans/2.0);    }    return 0;}