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

【HDOJ】1558 Segment set

时间:2014-12-30 00:22:45      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:

并查集+计算几何。

  1 /* 1558 */
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 
  6 #define MAXN 1005
  7 
  8 typedef struct {
  9     double x, y;
 10 } Point_t;
 11 
 12 typedef struct {
 13     Point_t b, e;
 14 } Seg_t;
 15 
 16 Seg_t segs[MAXN];
 17 int pre[MAXN];
 18 int ans[MAXN];
 19 
 20 int max(int a, int b) {
 21     return a>b ? a:b;
 22 }
 23 
 24 int min(int a, int b) {
 25     return a<b ? a:b;
 26 }
 27 
 28 double direction(Point_t p0, Point_t p1, Point_t p2) {
 29     return (p1.x-p0.x)*(p2.y-p0.y) - (p1.y-p0.y)*(p2.x-p0.x);
 30 }
 31 
 32 bool onSegment(Point_t p0, Point_t p1, Point_t p2) {
 33     if ( (min(p0.x, p1.x)<=p2.x && p2.x<=max(p0.x, p1.x)) && 34          (min(p0.y, p1.y)<=p2.y && p2.y<=max(p0.y, p1.y)) )
 35         return true;
 36     return false;
 37 }
 38 
 39 bool intersect(Seg_t x, Seg_t y) {
 40     Point_t p1 = x.b, p2 = x.e, p3 = y.b, p4 = y.e;
 41     double d1 = direction(p3, p4, p1);
 42     double d2 = direction(p3, p4, p2);
 43     double d3 = direction(p1, p2, p3);
 44     double d4 = direction(p1, p2, p4);
 45     if ( ((d1>0 && d2<0) || (d1<0 && d2>0)) && 46          ((d3>0 && d4<0) || (d3<0 && d4>0)) )
 47         return true;
 48     else if (d1==0 && onSegment(p3, p4, p1))
 49         return true;
 50     else if (d2==0 && onSegment(p3, p4, p2))
 51         return true;
 52     else if (d3==0 && onSegment(p1, p2, p3))
 53         return true;
 54     else if (d4==0 && onSegment(p1, p2, p4))
 55         return true;
 56     else
 57         return false;
 58 }
 59 
 60 int find(int x) {
 61     if (x == pre[x])
 62         return x;
 63     pre[x] = find(pre[x]);
 64     return pre[x];
 65 }
 66 
 67 void merge(int x, int y) {
 68     int fx = find(x);
 69     int fy = find(y);
 70     if (fx != fy) {
 71         pre[fy] = fx;
 72         ans[fx] += ans[fy];
 73         ans[fy] = 0;
 74     }
 75 }
 76 
 77 int main() {
 78     int t, n, m;
 79     int i, j, k;
 80     char cmd[3];
 81     
 82     #ifndef ONLINE_JUDGE
 83         freopen("data.in", "r", stdin);
 84     #endif
 85     
 86     scanf("%d", &t);
 87     while (t--) {
 88         scanf("%d", &n);
 89         for (i=1; i<=n; ++i) {
 90             pre[i] = i;
 91             ans[i] = 1;
 92         }
 93         m = 1;
 94         while (n--) {
 95             scanf("%s", cmd);
 96             if (cmd[0] == P) {
 97                 scanf("%lf%lf%lf%lf", &segs[m].b.x, &segs[m].b.y, &segs[m].e.x, &segs[m].e.y);
 98                 for (i=1; i<m; ++i) {
 99                     if (intersect(segs[i], segs[m]))
100                         merge(i, m);
101                 }
102                 ++m;
103             } else {
104                 scanf("%d", &j);
105                 k = find(j);
106                 printf("%d\n", ans[k]);
107             }
108         }
109         if (t)
110             printf("\n");
111     }
112     
113     return 0;
114 }

 

【HDOJ】1558 Segment set

标签:

原文地址:http://www.cnblogs.com/bombe1013/p/4192592.html

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