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

HDU 1558 Segment set (并查集+线段非规范相交)

时间:2014-08-15 17:30:29      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   ar   

题目链接

题意 : 如果两个线段相交就属于同一集合,查询某条线段所属集合有多少线段,输出。

思路 : 先判断与其他线段是否相交,然后合并。

bubuko.com,布布扣
  1 //1558
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <cmath>
  6 #define eps 1e-8
  7 #define zero(x) (((x) > 0 ? (x) : (-x)) < eps)
  8 
  9 using namespace std ;
 10 
 11 struct point
 12 {
 13     double x,y ;
 14 } p[1010];
 15 struct Line
 16 {
 17     point a;
 18     point b ;
 19 //    int num ;
 20 } L[1010] ;
 21 int father[1010],numb[1010],rankk[1010] ;
 22 int  cnt ;
 23 double direction(point p0,point p1,point p2)
 24 {
 25     return (p2.x-p0.x)*(p1.y-p0.y)-(p1.x-p0.x)*(p2.y-p0.y);
 26 }
 27 
 28 bool on_segment(point p0,point p1,point p2)
 29 {
 30     if((min(p0.x,p1.x)<=p2.x && p2.x<=max(p0.x,p1.x)) && (min(p0.y,p1.y)<=p2.y && p2.y<=max(p0.y,p1.y)))
 31         return true;
 32     return false;
 33 }
 34 
 35 bool Segment_intersect(point p1,point p2,point p3,point p4)
 36 {
 37     double d1,d2,d3,d4;
 38     d1 = direction(p3,p4,p1);
 39     d2 = direction(p3,p4,p2);
 40     d3 = direction(p1,p2,p3);
 41     d4 = direction(p1,p2,p4);
 42     if(((d1>0 && d2<0)||(d1<0 && d2>0)) && ((d3>0 && d4<0)||(d3<0&&d4>0)))
 43         return true;
 44     else if((d1==0 && on_segment(p3,p4,p1)) || (d2==0 && on_segment(p3,p4,p2)) || (d3==0 && on_segment(p1,p2,p3)) || (d4==0 && on_segment(p1,p2,p4)))
 45         return true;
 46     return false;
 47 }
 48 int find_(int x)
 49 {
 50     if(father[x] != x)
 51         father[x] = find_(father[x]) ;
 52     return father[x] ;
 53 }
 54 
 55 void mergee(int a, int b){
 56      int fx = find_(a);
 57      int fy = find_(b);
 58 
 59      if (fx != fy){
 60            father[fy] = fx;
 61            numb[fx] += numb[fy];
 62      }
 63 }
 64 void Init()
 65 {
 66     cnt = 0 ;
 67     for(int i=0; i<=1010; i++)
 68     {
 69         numb[i]=1;
 70     }
 71     for(int i = 0 ; i < 1010 ; i++)
 72         father[i] = i ;
 73     memset(rankk,0,sizeof(rankk)) ;
 74 }
 75 int main()
 76 {
 77     int T ,n,ss;
 78     scanf("%d",&T) ;
 79     char s[4] ;
 80     while( T--)
 81     {
 82         scanf("%d",&n) ;
 83         Init() ;
 84         for(int i = 0 ; i < n ; i++)
 85         {
 86             scanf("%s",s) ;
 87             if(s[0] == P)
 88             {
 89                 cnt ++ ;
 90                 scanf("%lf %lf %lf %lf",&L[cnt].a.x,&L[cnt].a.y,&L[cnt].b.x,&L[cnt].b.y) ;
 91                 for(int j = 1 ; j < cnt ; j ++)
 92                     if(find_(j) != find_(cnt) && Segment_intersect(L[j].a,L[j].b,L[cnt].a,L[cnt].b))
 93                         mergee(j,cnt) ;
 94             }
 95             else
 96             {
 97                 scanf("%d",&ss) ;
 98                 printf("%d\n",numb[find_(ss)]) ;
 99             }
100         }
101         if(T) printf("\n") ;
102     }
103     return 0 ;
104 }
View Code

线段非规范相交1

bubuko.com,布布扣
 1 double cross(point p0,point p1,point p2)
 2 {
 3     return (p2.x-p0.x)*(p1.y-p0.y)-(p1.x-p0.x)*(p2.y-p0.y);
 4 }
 5 
 6 bool on_segment(point p0,point p1,point p2)
 7 {
 8     if((min(p0.x,p1.x)<=p2.x && p2.x<=max(p0.x,p1.x)) && (min(p0.y,p1.y)<=p2.y && p2.y<=max(p0.y,p1.y)))
 9         return true;
10     return false;
11 }
12 
13 bool Segment_intersect(point p1,point p2,point p3,point p4)
14 {
15     double d1,d2,d3,d4;
16     d1 = cross(p3,p4,p1);
17     d2 = cross(p3,p4,p2);
18     d3 = cross(p1,p2,p3);
19     d4 = cross(p1,p2,p4);
20     if(((d1>0 && d2<0)||(d1<0 && d2>0)) && ((d3>0 && d4<0)||(d3<0&&d4>0)))
21         return true;
22     else if((d1==0 && on_segment(p3,p4,p1)) || (d2==0 && on_segment(p3,p4,p2)) || (d3==0 && on_segment(p1,p2,p3)) || (d4==0 && on_segment(p1,p2,p4)))
23         return true;
24     return false;
25 }
View Code

 

线段非规范相交2

bubuko.com,布布扣
 1 double cross(point a, point b, point c)
 2 {
 3     return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
 4 }
 5 
 6 //aa, bb为一条线段两端点 cc, dd为另一条线段的两端点 相交返回true, 不相交返回false
 7 bool intersect(point aa, point bb, point cc, point dd)
 8 {
 9     if ( max(aa.x, bb.x)<min(cc.x, dd.x) )
10     {
11         return false;
12     }
13     if ( max(aa.y, bb.y)<min(cc.y, dd.y) )
14     {
15         return false;
16     }
17     if ( max(cc.x, dd.x)<min(aa.x, bb.x) )
18     {
19         return false;
20     }
21     if ( max(cc.y, dd.y)<min(aa.y, bb.y) )
22     {
23         return false;
24     }
25     if ( cross(cc, bb, aa)*cross(bb, dd, aa)<0 )
26     {
27         return false;
28     }
29     if ( cross(aa, dd, cc)*cross(dd, bb, cc)<0 )
30     {
31         return false;
32     }
33     return true;
34 }
View Code

 

HDU 1558 Segment set (并查集+线段非规范相交),布布扣,bubuko.com

HDU 1558 Segment set (并查集+线段非规范相交)

标签:style   blog   http   color   os   io   for   ar   

原文地址:http://www.cnblogs.com/luyingfeng/p/3915149.html

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