hdu1558 Segment set

来源:互联网 发布:安全联盟认证知乎 编辑:程序博客网 时间:2024/05/17 05:00

屌丝真心觉得这题的计算几何味道远大于并查集,花了两天时间才想明白怎么判断两条直线相交,结果还写不对,。。。。。

code:

#include <cstdio>#include <cmath>using namespace std;const double eps=1e-8;int decmp(double n){    if(fabs(n)<eps)    {        return 0;    }    return n>0 ? 1:-1;}struct Point{    double x,y;};struct Seg{    Point s,e;}segs[1001];double direction(Point l,Point r,Point m){    //vector a (l.x-m.x,l.y-m.y)    //vector b (r.x-m.x,r.y-m.y)    return (l.x-m.x)*(r.y-m.y) - (r.x-m.x)*(l.y-m.y);}bool isIntersert(Seg a,Seg b){    int d1,d2,d3,d4;    d1=decmp(direction(a.s,a.e,b.s));    d2=decmp(direction(a.s,a.e,b.e));    d3=decmp(direction(b.s,b.e,a.s));    d4=decmp(direction(b.s,b.e,a.e));    //规范相交    if( d1*d2 <0 && d3*d4 <0)    {        return true;    }    //端点相交    if( d1*d2 ==0 || d3*d4==0 )    {        return true;    }    return false;}int num[1001],rank[1001],fa[1001];void init(){    for(int i=1;i<=1000;i++)    {        num[i]=1;        rank[i]=0;        fa[i]=i;    }}int find(int k){    if(k!=fa[k])    {        fa[k]=find(fa[k]);    }    return fa[k];}void merge(int x,int y){    if(!isIntersert(segs[x],segs[y]))    {        return ;    }    x=find(x);    y=find(y);    if(x!=y)    {        if(rank[x]<rank[y])        {            fa[x]=y;            num[y]+=num[x];        }else{            fa[y]=x;            num[x]+=num[y];            if(rank[x]==rank[y])            {                rank[x]++;            }        }    }}int main(){    int cas,n,cnt,i,j,k;    char str[2];    scanf("%d",&cas);    while(cas--)    {        scanf("%d",&n);        cnt=0;        init();        for(i=1;i<=n;i++)        {            scanf("%s",str);            if(str[0]=='P')            {                ++cnt;                scanf("%lf%lf",&segs[cnt].s.x,&segs[cnt].s.y);                scanf("%lf%lf",&segs[cnt].e.x,&segs[cnt].e.y);                for(j=1;j<cnt;j++)                {                    merge(j,cnt);                }            }else{                scanf("%d",&k);                k=find(k);                printf("%d\n",num[k]);            }        }        if(cas)        {            puts("");        }    }    return 0;}


原创粉丝点击