• hdu1558 Segment set


    题意:对每一个提问,求出第K条线段所在集合的线段数。

    所以相交的线段属于同一个集合

    分析:几何+并查集

    View Code
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<math.h>
    #define MAXN 1000+10
    using namespace std;
    struct Point
    {
    double x,y;
    };
    struct seg
    {
    Point a,b;
    }se[MAXN];
    int n,m,f[MAXN],r[MAXN];
    void init()
    {
    for(int i=0;i<m;i++)
    {
    f[i]=i;
    r[i]=1;
    }
    n=1;
    }

    float multiply(Point p1,Point p2,Point p0)
    {
    return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
    }
    //a(x1,y1),b(x2,y2)
    //x1*y2-x2*y1

    //确定两条线段是否相交
    int intersect(seg u,seg v)
    {
    return( (max(u.a.x,u.b.x)>=min(v.a.x,v.b.x))&& //u中最右的点是否在v最左的点的右边
    (max(v.a.x,v.b.x)>=min(u.a.x,u.b.x))&& //v中最右的点是否在u最左的点的右边
    //判断这两条线段在水平层面上是否可能相交
    (max(u.a.y,u.b.y)>=min(v.a.y,v.b.y))&& //u中最上的点是否在v最下的点的上边
    (max(v.a.y,v.b.y)>=min(u.a.y,u.b.y))&& //v中最上的点是否在u最下的点的上边
    //判断这两条线段在垂直层面上是否可能相交
    (multiply(v.a,u.b,u.a)*multiply(u.b,v.b,u.a)>=0)&&
    //判断v.a,v.b是否分布在u.b两侧(或线上)
    (multiply(u.a,v.b,v.a)*multiply(v.b,u.b,v.a)>=0));
    //判断u.a,u.b是否分布在v.a两侧(或线上)
    }

    int find(int x)
    {
    if(x==f[x])
    return f[x];
    f[x]=find(f[x]);
    return f[x];
    }
    void Union(int x,int y)
    {
    int a=find(x);
    int b=find(y);
    if(a==b) return ;
    f[a]=b;
    r[b]+=r[a];
    r[a]=0;
    }
    void addSeg()
    {
    for(int i=1;i<n;i++)
    {
    if(intersect(se[i],se[n])!=0)
    {
    // cout<<se[i].a.x<<' '<<se[i].a.y<<' '<<se[i].b.x<<' '<<se[i].b.y<<endl;
    // cout<<se[n].a.x<<' '<<se[n].a.y<<' '<<se[n].b.x<<' '<<se[n].b.y<<endl;
    // cout<<i<<"and"<<n<<endl;
    Union(i,n);
    }
    }
    n++;
    }
    int main()
    {
    int T,cas=0;
    char str[2];
    scanf("%d",&T);
    while(T--)
    {
    if(cas)
    puts("");
    cas++;
    scanf("%d",&m);
    init();
    int k;
    while(m--)
    {
    scanf("%s",str);
    if(str[0]=='P')
    {
    scanf("%lf %lf %lf %lf",&se[n].a.x,&se[n].a.y,&se[n].b.x,&se[n].b.y);
    addSeg();
    }
    else {
    scanf("%d",&k);
    printf("%d\n",r[find(k)]);
    }
    }
    }
    return 0;
    }
  • 相关阅读:
    Microsoft Office MIME Types
    启动mongodb
    学习Hbase API的一个视频
    报错:Hive Runtime Error while processing row
    821. Shortest Distance to a Character
    1171. Remove Zero Sum Consecutive Nodes from Linked List
    190. Reverse Bits
    Rust--如何实现内存安全的?
    Rust -- as_ref与borrow的区别
    653. Two Sum IV
  • 原文地址:https://www.cnblogs.com/nanke/p/2352880.html
Copyright © 2020-2023  润新知