HDU1558 Segment set(计算几何+并查集)

来源:互联网 发布:大数据人工智能培训 编辑:程序博客网 时间:2024/05/16 06:24

题意:给你一些线段,问与第i根线段相交的线段有几根。。

思路:计算几何+并查集

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>using namespace std;const int N = 1009;const double INF = 1e20 , EPS = 1E-6;bool zero(double x){    return -EPS<x&&x<EPS;}struct cvector{    double x,y;    cvector(){};    cvector(double a,double b){x=a,y=b;}};double operator^(cvector p,cvector q){    return p.x*q.y-q.x*p.y;}double operator *(cvector p,cvector q){    return p.x*q.x+p.y*q.y;}struct cpoint{    double x,y;    cpoint(double a,double b){        x = a,y = b;    }    cpoint(){}};cvector operator -(cpoint a, cpoint b){   ///向量ab    return cvector(b.x-a.x, b.y-a.y);}struct cline{    cpoint a,b;} re[N];bool dots_inline(cpoint p1,cpoint p2,cpoint p3){///判三点共线return zero((p2-p1)^(p3-p1));}bool same_side(cpoint p1,cpoint p2,cline l){  ///两点在线段同侧    cvector v0=l.b-l.a;    cvector v1=p1-l.a,v2=p2-l.a;    return (v1^v0)*(v2^v0)>EPS;}bool dot_onseg(cpoint p,cline ll){    /// 点在线段上    if(!dots_inline(p,ll.a,ll.b)) return false;    cvector v1=ll.b-ll.a,v2=p-ll.a;    cvector v3=ll.a-ll.b,v4=p-ll.b;    if(v1*v2>-EPS&&v3*v4>-EPS) return true;    return false;}bool intersect_in(cline u,cline v){   ///线段相交,包括交点和重合    if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))        return !same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);    return dot_onseg(u.a,v)||dot_onseg(u.b,v)    ||dot_onseg(v.a,u)||dot_onseg(v.b,u);}int fa[N];int finfa(int k){    if(fa[k]==k) return k;    return fa[k] = finfa(fa[k]);}void un(int a,int b){    fa[finfa(a)] = fa[finfa(b)];}bool xx(int a,int b){    return intersect_in(re[a],re[b]);}int main(){    freopen("in.txt","r",stdin);    int cas,ou=0,n,tmp,cnt;    char ar[3];    cpoint a,b;    scanf("%d",&cas);    while(cas--)    {        cnt = 0;        if(ou) printf("\n");ou = true;        scanf("%d",&n);        for(int i=0;i<=n;i++) fa[i] = i;        while(n--)        {            scanf("%s",ar);            if(ar[0]=='P')            {                scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);                re[cnt].a=a,re[cnt].b=b;                for(int i=0;i<cnt;i++)                {                    if(finfa(i)!=finfa(cnt)&&xx(i,cnt))                    {                        un(i,cnt);                    }                }cnt++;            }            else            {                scanf("%d",&tmp);tmp--;                //cout<<tmp<<" "<<cnt<<endl;                int f = finfa(tmp),ans = 0;                for(int i=0;i<cnt;i++)                if(finfa(i)==f) ans++;                printf("%d\n",ans);            }        }    }    return 0;}


原创粉丝点击