Problem 2194 星系碰撞

Accept: 14    Submit: 48
Time Limit: 30000 mSec    Memory Limit : 327680 KB

 Problem Description

据预测,大约在100亿年后,狮子座星系将与银河系发生碰撞,两个星系的碰撞将会合并两个星系,但是没有2个星球会相撞。现在某科学家得到两个星系合并后的结果,一些二维平面上的点,但是不知道那些星球属于银河系,已知如果两个星球属于同一个星系,那么他们之间的距离大于5光年,这边的距离指的是欧几里得距离,即(x1,y1)与(x2,y2)的距离为sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))。现在想请你帮忙把合并后的结果分成2个集合,一个属于银河系,一个属于狮子座星系,由于集合划分的方案可能有多种,现在想知道最多有多少个星球可能属于银河系。(可以所有星球都属于银河系)

例如:如下图有6个点,你可以有以下4中划分{{1, 2, 4, 5}, {3, 6}}; {{1, 2, 3, 4}, {5, 6}}; {{1, 4,5}, {2, 3, 6}}; {{1, 3, 4}, {2, 5, 6}} ,那么可以采用第一种划分{1,2,4,5} 都属于银河系,答案为4.

 Input

包含多组数据 每组数据输入第一行 一个整数N 表示星球个数(1<=N<=50000),接下去N 行 每行2个整数 x和y 表示星球的坐标(1<=x,y<=500000),没有重合的点。

 Output

输出一行一个整数表示最多有多少个星球属于银河系。如果没办法进行划分那么输出-1。

 Sample Input

6
1 3
9 1
11 7
5 7
13 5
4 4

 Sample Output

4
分析:把所有的行星按照x坐标从小到大排序,然后枚举两点(加剪枝)距离,若距离小于等于5,若这两个点不在一个集合当中,则加入一个集合,并且这两个相连的点染为不同的颜色,若这两个点在一个集合当中,则判定矛盾,因为再改集合中至少有三个点,他们两两之间的距离都小于等于5,就是说无论怎样分配他们都无法满足题目要求,如果不存在矛盾的情况,则计算出每个集合当中被染成两种颜色的个数max1和max2,最后把所有集合当中的较大者加起来即:sum+=max(max1[k]+max2[k])(k属于不同的集合)
程序;
  1. #include"stdio.h"
  2. #include"string.h"
  3. #include"math.h"
  4. #include"iostream"
  5. #include"queue"
  6. #include"algorithm"
  7. #include"stack"
  8. #include"map"
  9. #include"string"
  10. #define M 50009
  11. #define inf 0x3f3f3f3f
  12. #define eps 1e-9
  13. #define LL __int64
  14. using namespace std;
  15. struct node
  16. {
  17. int x,y;
  18. }p[M];
  19. int cmp(node a,node b)
  20. {
  21. return a.x<b.x;
  22. }
  23. LL dist(node a,node b)
  24. {
  25. return (LL)(a.x-b.x)*(a.x-b.x)+(LL)(a.y-b.y)*(a.y-b.y);
  26. }
  27. int f[M],max1[M],max2[M],sum[M];
  28. int finde(int x)
  29. {
  30. if(x!=f[x])
  31. {
  32. int t=f[x];
  33. f[x]=finde(f[x]);
  34. sum[x]=(sum[x]+sum[t])%2;
  35. }
  36. return f[x];
  37. }
  38. int ok(int n)
  39. {
  40. for(int i=0;i<n;i++)
  41. {
  42. f[i]=i;
  43. sum[i]=0;
  44. }
  45. for(int i=0;i<n;i++)
  46. {
  47. for(int j=i+1;j<n;j++)
  48. {
  49. if(p[j].x-p[i].x>5)break;
  50. if(dist(p[i],p[j])<=25LL)
  51. {
  52. int x=finde(i);
  53. int y=finde(j);
  54. if(x!=y)
  55. {
  56. f[y]=x;
  57. sum[y]=(sum[x]+sum[i]+1-sum[j])%2;
  58. }
  59. else
  60. {
  61. if(sum[x]==sum[y])
  62. return -1;
  63. }
  64.  
  65. }
  66. }
  67. }
  68. memset(max1,0,sizeof(max1));
  69. memset(max2,0,sizeof(max2));
  70. for(int i=0;i<n;i++)
  71. {
  72. int y=finde(i);
  73. f[i]=y;
  74. if(sum[i]==0)
  75. max1[y]++;
  76. else
  77. max2[y]++;
  78. }
  79. int ans=0;
  80. for(int i=0;i<n;i++)
  81. {
  82. if(f[i]==i)
  83. {
  84. ans+=max(max1[i],max2[i]);
  85. }
  86. }
  87. return ans;
  88. }
  89. int main()
  90. {
  91. int n;
  92. while(~scanf("%d",&n))
  93. {
  94. for(int i=0;i<n;i++)
  95. {
  96. scanf("%d%d",&p[i].x,&p[i].y);
  97. }
  98. sort(p,p+n,cmp);
  99. printf("%d\n",ok(n));
  100. }
  101. return 0;
  102. }

  

Fzu oj2194星系碰撞(排序+并查集+路径压缩)的更多相关文章

  1. 并查集+路径压缩(poj1988)

    http://poj.org/problem?id=1988 Cube Stacking Time Limit: 2000MS   Memory Limit: 30000K Total Submiss ...

  2. hdu 1558 线段相交+并查集路径压缩

    Segment set Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. 【数轴涂色+并查集路径压缩+加速】C. String Reconstruction

    http://codeforces.com/contest/828/problem/C [题意] [思路] 因为题目保证一定有解,所有优化时间复杂度的关键就是不要重复染色,所以我们可以用并查集维护区间 ...

  4. 并查集 + 路径压缩(经典) UVALive 3027 Corporative Network

    Corporative Network Problem's Link Mean: 有n个结点,一开始所有结点都是相互独立的,有两种操作: I u v:把v设为u的父节点,edge(u,v)的距离为ab ...

  5. HDU 3635 并查集+路径压缩+记录每个点移动次数

    题意: 给定n个点 oper个操作 每个点有1个龙珠 下面2种操作: T u v 把u点所有龙珠搬到v Q u  问u点当前所在城市 u点所在城市有几个龙珠 u点被移动几次 思路: 并查集可以求出 u ...

  6. HDOJ 3635 并查集- 路径压缩,带秩合并

    思路来源:http://blog.csdn.net/niushuai666/article/details/6990421 题目大意: 初始时,有n个龙珠,编号从1到n,分别对应的放在编号从1到n的城 ...

  7. LA 并查集路径压缩

    题目大意:有n个节点,初始时每个节点的父亲节点都不存在.有两种操作 I u v:把点节点u的父亲节点设为v,距离为|u-v|除以1000的余数.输入保证执行指令前u没有父亲节点. E u:询问u到根节 ...

  8. POJ 1988 Cube Stacking(并查集+路径压缩)

    题目链接:id=1988">POJ 1988 Cube Stacking 并查集的题目 [题目大意] 有n个元素,開始每一个元素自己 一栈.有两种操作,将含有元素x的栈放在含有y的栈的 ...

  9. snnu(1110) 传输网络 (并查集+路径压缩+离线操作 || 线段树)

    1110: 传输网络 Time Limit: 3 Sec  Memory Limit: 512 MBSubmit: 43  Solved: 18[Submit][Status][Web Board] ...

随机推荐

  1. delphi下TList的用法

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  2. linux下线程调用sleep,进程挂起

    http://blog.csdn.net/horstlinux/article/details/7911457 http://blog.csdn.net/eroswang/article/detail ...

  3. Python的运行

    1.在命令行中运行 2.使用shell(IDLE) 3.新建.py脚本 只要是编辑器都可以 4.脚本在IDLE中运行 5.在windows下的cmd下运行脚本

  4. backgroundworker的应用

    一种情况是当凭证界面加载时,因为加载项比较多,辅助项的处理,可以应用backgroundworker启用另一线程进行加载,不影响当前界面的显示,提高响应速度. 情况2 是月末结转余额时,因为用时间较长 ...

  5. JMeter学习-013-JMeter 逻辑控制器之-如果(If)控制器

    前文简述了 JMeter 如何通过 HTTP Cookie管理器,实现了在不执行登录操作的情况下,通过 Cookie 实现登录态的操作,具体请参阅:JMeter学习-012-JMeter 配置元件之- ...

  6. Selenium2学习-008-WebUI自动化实战实例-006-易迅登录之 frame 处理

    此文主要讲述用 Java 编写 Selenium 自动化测试脚本编写过程中,在因 frame 标签导致页面定位失败,提示 NoSuchElementException 时的,页面元素定位前的 fram ...

  7. Ubuntu下面安装eclipse for c++

    1.下载jdk,cdt,eclipse. 其中jdk是java运行环境,eclipse需要先装jre,才可能运行,cdt是在eclipse中运行c\c++程序的插件.jdk安装见上文. 2.eclip ...

  8. ClassLoader

    1.双亲委派制 ClassLoadder是一个abstract类 static class sun.misc.Launcher$ExtClassLoader extends java.net.URLC ...

  9. LeetCode Longest Increasing Path in a Matrix

    原题链接在这里:https://leetcode.com/problems/longest-increasing-path-in-a-matrix/ Given an integer matrix, ...

  10. LintCode A + B Problem

    原题链接在这里:http://www.lintcode.com/en/problem/a-b-problem/ 不让用 数学运算符,就用位运算符. a的对应位 ^ b的对应位 ^ carry 就是re ...