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