杭电 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");
    }
}

 

posted @ 2013-03-26 21:52  SF-_-  阅读(241)  评论(0编辑  收藏  举报