杭电 HOJ 1588 Segment set 解题报告

   并查集,还有判断两线段是否相交。我直接用面积的方法判断的,貌似效率略低,但是Ac还是可以的,代码如下:

#include <iostream>

using namespace std;



int root[1001];

int num[1001];



int find(int x)

{

    return root[x]?(root[x]=find(root[x])):x;

}



void u(int x,int y)

{

    int a=find(x);

    int b=find(y);

    if(a!=b)

        num[root[b]=a]+=num[b];

}



struct p

{

    double x1,y1,x2,y2;

} line[1001];



double area(double a,double b,double c,double d)

{

    return (a*d-b*c);

};



bool across(p &a,p &b)

{

    if(area(a.x2-a.x1,a.y2-a.y1,b.x1-a.x1,b.y1-a.y1)*area(a.x2-a.x1,a.y2-a.y1,b.x2-a.x1,b.y2-a.y1)<=0

        &&

        area(b.x2-b.x1,b.y2-b.y1,a.x1-b.x1,a.y1-b.y1)*area(b.x2-b.x1,b.y2-b.y1,a.x2-b.x1,a.y2-b.y1)<=0)

        return true;

    return false;

}



int main()

{

    char s[2];

    int cas,m,n,i,j,ans,t;

    scanf("%d",&cas);

    while(cas--)

    {

        m=1;

        memset(root,0,sizeof(root));

        memset(num,0,sizeof(num));



        scanf("%d",&n);

        for(int i=0;i<n;i++)

        {

            scanf("%s",s);

            if(s[0]=='P')

            {

                scanf("%lf%lf%lf%lf",&line[m].x1,&line[m].y1,&line[m].x2,&line[m].y2);

                root[m]=0;

                num[m]=1;

                for(j=1;j<m;j++)

                    if(across(line[j],line[m]))

                        u(m,j);

                m++;

            }

            else

            {

                scanf("%d",&t);

                printf("%d\n",num[find(t)]);

            }

        }

        if(cas)

            printf("\n");

    }

}

 

你可能感兴趣的:(set)