【bzoj1604/Usaco2008 Open】Cow Neighborhoods 奶牛的邻居——平衡树+并查集

Description

了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l≤Xi,Yi≤[1..10^9];Xi,Yi∈整数.当满足下列两个条件之一,两只奶牛i和j是属于同一个群的:
  1.两只奶牛的曼哈顿距离不超过C(1≤C≤10^9),即lXi - xil+IYi - Yil≤C.
  2.两只奶牛有共同的邻居.即,存在一只奶牛k,使i与k,j与k均同属一个群.
    给出奶牛们的位置,请计算草原上有多少个牛群,以及最大的牛群里有多少奶牛

Input

   第1行输入N和C,之后N行每行输入一只奶牛的坐标.

Output

仅一行,先输出牛群数,再输出最大牛群里的牛数,用空格隔开.

Sample Input

4 2
1 1
3 3
2 2
10 10

* Line 1: A single line with a two space-separated integers: the
number of cow neighborhoods and the size of the largest cow
neighborhood.

Sample Output

2 3

OUTPUT DETAILS:
There are 2 neighborhoods, one formed by the first three cows and
the other being the last cow. The largest neighborhood therefore
has size 3.
 

题解参考hzwer的->戳这里
代码:
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<set>
 5 #define mem(a,p) memset(a,p,sizeof(a))
 6 typedef long long LL;
 7 const LL inf=1e18;
 8 const int N=1e5+10;
 9 using std::sort;
10 using std::max;
11 using std::abs;
12 struct node{LL x,y;int id;}e[N];
13 bool operator <(node a,node b){return a.y<b.y;}   
14 typedef std::multiset<node>me;
15 typedef me::iterator IT;
16 int n,c,mx=0,ton[N],fa[N];
17 me mset;
18 bool cmp(node aa,node bb){return aa.x<bb.x;}
19 int read(){
20     int ans=0,f=1;char c=getchar();
21     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
22     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
23     return ans*f;
24 }
25 int ans;
26 int find(int x){
27     if(x==fa[x])return x;
28     fa[x]=find(fa[x]);
29     return fa[x];
30 }
31 void merge(int x,int y){
32     x=find(x);y=find(y);
33     if(x!=y){
34         fa[y]=x;ans--;
35     }
36 }
37 void work(){
38     int h=1;mset.insert((node){0,inf,0});mset.insert((node){0,-inf,0});
39     mset.insert(e[1]);
40     for(int i=2;i<=n;i++){
41         while(h<i&&e[i].x-e[h].x>c){
42             IT it=mset.find(e[h]);
43             mset.erase(it);
44             h++;
45         }
46         IT it=mset.lower_bound(e[i]),it1=--it;it++;
47         if(it1->y>=e[i].y-c)merge(e[i].id,it1->id);
48         if(it->y<=e[i].y+c)merge(e[i].id,it->id);
49         mset.insert(e[i]);
50     }
51 }
52 int main(){
53     n=read();c=read();ans=n;
54     for(int i=1,x,y;i<=n;i++){
55         x=read();y=read();
56         e[i].x=x+y;e[i].y=x-y;e[i].id=i;
57         fa[i]=i;
58     }
59     sort(e+1,e+1+n,cmp);
60     work();
61     for(int i=1;i<=n;i++)ton[find(i)]++;
62     for(int i=1;i<=n;i++)mx=max(mx,ton[i]);
63     printf("%d %d\n",ans,mx);
64     return 0;
65 }
66 
bzoj1604

 

posted @ 2017-10-14 10:35  Child-Single  阅读(161)  评论(0编辑  收藏  举报