码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 1558 线段相交+并查集

时间:2014-12-12 13:11:37      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   ar   color   os   sp   for   on   

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

 

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 }

 

hdu 1558 线段相交+并查集

标签:style   blog   io   ar   color   os   sp   for   on   

原文地址:http://www.cnblogs.com/pdev/p/4159323.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!