hdu 1558 Segment set (computational geometry + union search set)

Question link
idea: The question meaning is to determine how many line segments there are in the set of the query line segment, so it is natural to think of and check the set to determine the size of the set, calculate by the way when merging, and record it as your first simple question .

#include<cstdio>
#include<cmath>
#include<cstring>
#define lk (k<<1)
#define rk (k<<|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pi=acos(-1);
const double eps=1e-8;
const int inf=0x3f3f3f3f;
const int N=1e3+10;
int fa[N],cnt,num[N];
int sgn(double x)
{
    
    
    if(fabs(x)<eps) return 0;
    else return x<0?-1:1;
}
int find(int k)
{
    
    
    if(fa[k]!=k) fa[k]=find(fa[k]);
    return fa[k];
}
struct point
{
    
    
    double x,y;
    point(double xx=0,double yy=0):x(xx),y(yy){
    
    }
    point operator + (point a){
    
    return point(x+a.x,y+a.y);}
    point operator - (point a){
    
    return point(x-a.x,y-a.y);}
    point operator * (double k){
    
    return point(x*k,y*k);}
    point operator / (double k){
    
    return point(x/k,y/k);}
};
double cross(point a,point b)
{
    
    
    return a.x*b.y-a.y*b.x;
}
struct line
{
    
    
    point p1,p2;
    line(){
    
    }
    line(point p11,point p22):p1(p11),p2(p22){
    
    }
};
bool cross_seg(point a,point b,point c,point d)
{
    
    
    double c1=cross(c-a,b-a),c2=cross(d-a,b-a);
    double d1=cross(d-c,b-c),d2=cross(d-c,a-c);
    if(sgn(c1)*sgn(c2)<=0&&sgn(d1)*sgn(d2)<=0) return 1;
    return 0;
}
line l[N];
int main()
{
    
    
    int t;
    scanf("%d",&t);
    while(t--){
    
    
        memset(num,0,sizeof(num));
        int q;
        cnt=0;
        scanf("%d",&q);
        for(int i=1;i<=q;i++) fa[i]=i;
        while(q--){
    
    
            char s[3];
            double x1,y1,x2,y2;
            scanf("%s",s);
            if(s[0]=='P'){
    
    
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                l[++cnt]=line(point(x1,y1),point(x2,y2));
                num[cnt]++;
                for(int i=1;i<cnt;i++){
    
    
                    if(cross_seg(l[i].p1,l[i].p2,l[cnt].p1,l[cnt].p2)){
    
    
                        int r1=find(i);
                        int r2=find(cnt);
                        if(r1!=r2){
    
    
                            fa[r2]=r1;
                            num[r1]+=num[r2];
                        }
                    }
                }
            }
            else {
    
    
                int k;
                scanf("%d",&k);
                int r=find(k);
                printf("%d\n",num[r]);
            }
        }
        if(t) printf("\n");
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/amazingee/article/details/108550630