zoukankan      html  css  js  c++  java
  • hdu 1558 线段相交+并查集

    题意:要求相交的线段都要塞进同一个集合里

         

    sol:并查集+判断线段相交即可。n很小所以n^2就可以水过

      1 #include <iostream>
      2 #include <cmath>
      3 #include <cstring>
      4 #include <cstdio>
      5 using namespace std;
      6 
      7 int f[1010];
      8 char ch;
      9 int tmp,n;
     10 double X1,X2,Y1,Y2;
     11 
     12    #define eps 1e-8
     13    #define PI acos(-1.0)//3.14159265358979323846
     14    //判断一个数是否为0,是则返回true,否则返回false
     15    #define zero(x)(((x)>0?(x):-(x))<eps)
     16    //返回一个数的符号,正数返回1,负数返回2,否则返回0
     17    #define _sign(x)((x)>eps?1:((x)<-eps?2:0))
     18   struct point
     19   {
     20       double x,y;
     21       point(){}
     22       point(double xx,double yy):x(xx),y(yy)
     23       {}
     24   };
     25   struct line
     26   {
     27       point a,b;
     28       line(){}      //默认构造函数
     29       line(point ax,point bx):a(ax),b(bx)
     30       {}
     31   }l[1010];//直线通过的两个点,而不是一般式的三个系数
     32 
     33    //求矢量[p0,p1],[p0,p2]的叉积
     34    //p0是顶点
     35    //若结果等于0,则这三点共线
     36    //若结果大于0,则p0p2在p0p1的逆时针方向
     37    //若结果小于0,则p0p2在p0p1的顺时针方向
     38    double xmult(point p1,point p2,point p0)
     39    {
     40        return(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
     41    }
     42    //计算dotproduct(P1-P0).(P2-P0)
     43    double dmult(point p1,point p2,point p0)
     44    {
     45        return(p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
     46    }
     47    //两点距离
     48    double distance(point p1,point p2)
     49    {
     50        return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
     51    }
     52    //判三点共线
     53    int dots_inline(point p1,point p2,point p3)
     54    {
     55        return zero(xmult(p1,p2,p3));
     56    }
     57    //判点是否在线段上,包括端点
     58    int dot_online_in(point p,line l)
     59    {
     60        return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps;
     61    }
     62    //判点是否在线段上,不包括端点
     63    int dot_online_ex(point p,line l)
     64    {
     65        return dot_online_in(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y))&&(!zero(p.x-l.b.x)||!zero(p.y-l.b.y));
     66    }
     67    //判两点在线段同侧,点在线段上返回0
     68    int same_side(point p1,point p2,line l)
     69    {
     70        return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;
     71    }
     72    //判两点在线段异侧,点在线段上返回0
     73    int opposite_side(point p1,point p2,line l)
     74    {
     75        return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;
     76    }
     77    //判两直线平行
     78    int parallel(line u,line v)
     79    {
     80        return zero((u.a.x-u.b.x)*(v.a.y-v.b.y)-(v.a.x-v.b.x)*(u.a.y-u.b.y));
     81    }
     82    //判两直线垂直
     83    int perpendicular(line u,line v)
     84    {
     85        return zero((u.a.x-u.b.x)*(v.a.x-v.b.x)+(u.a.y-u.b.y)*(v.a.y-v.b.y));
     86    }
     87    //判两线段相交,包括端点和部分重合
     88    int intersect_in(line u,line v)
     89    {
     90        if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))
     91            return!same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);
     92        return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u);
     93    }
     94 int find(int x)
     95 {
     96     if (f[x]!=x)
     97         f[x]=find(f[x]);
     98     return f[x];
     99 }
    100 
    101 void iunion(int x,int y)
    102 {
    103     int fx,fy;
    104     fx=find(x);
    105     fy=find(y);
    106     if (fx!=fy)
    107         f[fx]=fy;
    108 }
    109 
    110 int main()
    111 {
    112     //freopen("in.txt","r",stdin);
    113     int times;
    114     cin>>times;
    115     while(times--)
    116     {
    117 
    118     cin>>n;
    119     int T=0;
    120     for (int i=1;i<=n;i++)
    121     {
    122         /*
    123         cout<<"dev: ";
    124         for (int j=1;j<=T;j++)
    125             cout<<f[j]<<" ";
    126         cout<<endl;
    127         */
    128         cin>>ch;
    129         if (ch=='Q')
    130         {
    131             cin>>tmp;
    132             int ans=0;
    133             for (int j=1;j<=T;j++)
    134                 if (find(tmp)==find(j))     ans++;
    135             cout<<ans<<endl;
    136         }
    137         else if (ch=='P')
    138         {
    139             cin>>X1>>Y1>>X2>>Y2;
    140             T++;
    141             f[T]=T;
    142             l[T]=line(point(X1,Y1),point(X2,Y2));
    143             //cout<<l[T].a.x<<" "<<l[T].a.y<<" "<<l[T].b.x<<" "<<l[T].b.y<<endl;
    144             for (int j=1;j<T;j++)
    145                 if (intersect_in(l[T],l[j])>0)
    146                     iunion(j,T);
    147         }
    148     }
    149 
    150     if (times>0)
    151         cout<<endl;
    152     }
    153     return 0;
    154 }
  • 相关阅读:
    适用于SQL Server生产环境DBA的七大技巧
    Android网络收音机项目(源码实例分享)
    利用antzip包来进行解压与压缩
    开发网站客户端第二弹
    Android 4.1源代码今日将发布
    Android 4.1 Jelly Bean(果冻豆) SDK4.1最新下载
    Google I/O 2012 主题演讲直播(第一天)Android 4.1 Jelly Bean们来了
    android水果连连看开发实例【源码下载有背景音乐、音效】
    android魔法泡泡动画分析(附源码)
    优亿移动开放日第十五期:优亿开发行业数据报告
  • 原文地址:https://www.cnblogs.com/pdev/p/4159323.html
Copyright © 2011-2022 走看看