zoukankan      html  css  js  c++  java
  • HDU 1558 Segment set (并查集+线段非规范相交)

    题目链接

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

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

      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
    ",numb[find_(ss)]) ;
     99             }
    100         }
    101         if(T) printf("
    ") ;
    102     }
    103     return 0 ;
    104 }
    View Code

    线段非规范相交1

     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

     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
  • 相关阅读:
    《Maven实战》第6章 仓库
    Log4j2中的同步日志与异步日志
    CSDN VIP如何添加自定义栏目
    CSDN VIP如何添加引流自定义栏目
    kubernetes垃圾回收器GarbageCollector Controller源码分析(二)
    java图形验证码实现
    java这个404你能解决吗?
    innodb笔记
    java项目启动脚本
    服务器初始化脚本
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3915149.html
Copyright © 2011-2022 走看看