线段相交与并查集(bnu5753,hdu1558)

线段相交与并查集(bnu5753,hdu1558)
这个主要是线段相交的处理,完全按照算法导论写一下几何就好了。并查集不想再说了。
叉积是好东西,同学们必须学会。
  1  #include < iostream >
  2  #include < cstdio >
  3  #include < algorithm >
  4  #include < iomanip >
  5  using   namespace  std;
  6  const   int  maxnum = 1000 + 1 ;
  7  #define  rep(i,n,m) for(int i=(n);i<=(m);++i)
  8  #define  re1(i,n) rep(i,1,n)
  9  struct  point{
 10       double  x,y;
 11      point(){
 12 
 13      }
 14      point( double   x, double  y):x(x),y(y){
 15 
 16      }
 17      friend ostream &   operator << (ostream  & out ,point a){
 18           out << ' ( ' << a.x << ' , ' << a.y << ' ) ' ;
 19           return   out ;
 20      }
 21  };
 22  struct  seg{
 23       double  x,y;
 24      point from,to;
 25      seg(){
 26 
 27      }
 28      seg(point a,point b):from(a),to(b){
 29           double  x1 = a.x,x2 = b.x;
 30           double  y1 = a.y,y2 = b.y;
 31          x = x2 - x1;
 32          y = y2 - y1;
 33      }
 34  };
 35  double  cross(seg a,seg b){
 36       double  x1 = a.x,x2 = b.x;
 37       double  y1 = a.y,y2 = b.y;
 38       return  x1 * y2 - y1 * x2;
 39  }
 40  double  cross(point p0,point p1,point p2){
 41       return  cross(seg(p0,p1),seg(p0,p2));
 42  }
 43  bool  between( double  a, double  b, double  x){
 44       return  x >= &&  x <= b;
 45  }
 46  bool  on_seg(point p1,point p2,point p0){
 47       double  x1 = p1.x,x2 = p2.x;
 48       double  y1 = p1.y,y2 = p2.y;
 49       return  between(min(x1,x2),max(x1,x2),p0.x)  &&  between(min(y1,y2),max(y1,y2),p0.y);
 50  }
 51  bool  intersect(point p1,point p2,point p3,point p4){
 52       int  d1 = cross(p3,p4,p1);
 53       int  d2 = cross(p3,p4,p2);
 54       int  d3 = cross(p1,p2,p3);
 55       int  d4 = cross(p1,p2,p4);
 56       if (((d1 > 0   &&  d2 < 0 ) || (d1 < 0   &&  d2 > 0 ))  && ((d3 > 0   &&  d4 < 0 || (d3 < 0   &&  d4 > 0 )))
 57           return   true ;
 58       else   if (d1 == 0   &&  on_seg(p3,p4,p1))
 59           return   true ;
 60       else   if (d2 == 0   &&  on_seg(p3,p4,p2))
 61           return   true ;
 62       else   if (d3 == 0   &&  on_seg(p1,p2,p3))
 63           return   true ;
 64       else   if (d4 == 0   &&  on_seg(p1,p2,p4))
 65           return   true ;
 66       else  
 67           return   false ;
 68      
 69  }
 70  struct  seg segs[maxnum];
 71  int  G[maxnum];
 72  int  num[maxnum];
 73  int  find( int  x){
 74       if (G[x] != x)
 75          G[x] = find(G[x]);
 76       return  G[x];
 77  }
 78  void  u3n( int  a, int  b){
 79       int  x = find(a);
 80       int  y = find(b);
 81       if (x == y)
 82           return ;
 83      G[x] = y;
 84      num[y] += num[x];
 85  }
 86  void  showline( int  n, int  m){
 87      rep(i,n,m){
 88          cout << setw( 6 ) << i;
 89      }
 90      cout << endl << endl;
 91  }
 92  template < class  T >
 93  void  show(T  * a, int  n, int  m){
 94      rep(i,n,m){
 95          cout << setw( 6 ) << a[i];
 96      }
 97      cout << endl;
 98  }
 99  int  main(){    
100       int  tcase;
101      scanf( " %d " , & tcase);
102       while (tcase -- ){
103           int  m,n = 0 ;
104          scanf( " %d " , & m);
105           char  cmd[ 2 ];
106          re1(u,m){
107              G[u] = u;
108              num[u] = 1 ;
109          }
110          re1(u,m){
111              scanf( " %s " ,cmd);
112               if (cmd[ 0 ] == ' P ' ){
113                   double  x1,y1,x2,y2;
114                  scanf( " %lf%lf%lf%lf " , & x1, & y1, & x2, & y2);
115                  segs[ ++ n] = seg(point(x1,y1),point(x2,y2));        
116           //         cout<<segs[n].from<<' '<<segs[n].to<<endl;
117                  re1(i,n - 1 ){
118                       if (intersect(segs[i].from,segs[i].to,segs[n].from,segs[n].to))
119                          u3n(i,n);
120                  }
121              } else {
122                   int  id;
123                  scanf( " %d " , & id);
124                  printf( " %d\n " ,num[find(id)]);
125              }
126          }
127           // showline(1,6);
128           // show(G,1,6);
129           // show(num,1,6);
130           if (tcase)
131              printf( " \n " );
132      }
133  }

你可能感兴趣的:(线段相交与并查集(bnu5753,hdu1558))