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

## Description

1．两只奶牛的曼哈顿距离不超过C(1≤C≤10^9)，即lXi - xil+IYi - Yil≤C.
2．两只奶牛有共同的邻居．即，存在一只奶牛k，使i与k，j与k均同属一个群．
给出奶牛们的位置，请计算草原上有多少个牛群，以及最大的牛群里有多少奶牛

## Input

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

## 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.

 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;}
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(){
54     for(int i=1,x,y;i<=n;i++){
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  阅读(109)  评论(0编辑  收藏  举报