bzoj 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集)
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.
HINT
Source
【思路】
Set+并查集
曼哈顿距离分为以下情况
X-x+Y-y -> (X+Y)-(x+y)
X-x+y-Y -> (X-Y)-(x-y)
x-X+Y-y -> -( (X-Y)-(x-y) )
x-X+y-Y -> -( (X+Y)-(x+y) )
这四种情况,我们可以发现,答案就是
max( |(X+Y)-(x+y)|, |(X-Y)-(x-y)| )
于是把每个点变为(x+y,x-y) 并将x从小到大排序
维护一个队列使得front~i区间x坐标的差均小于c
用set维护队列元素中的y,如果i在set中的前驱或后继与i的y之差小于c则合并集合。
【代码】
1 #include<set> 2 #include<cstdio> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long LL; 8 const int N = 1e5+10; 9 const int INF = 1e9+1e9+7; 10 struct Node{ 11 int x,y; 12 bool operator < (const Node& rhs) const{ 13 return x<rhs.x; 14 } 15 }a[N]; 16 int n,c,p[N],sum[N],ans,mx; 17 multiset<Node> S; 18 multiset<Node> ::iterator it; 19 20 int ifind(int u) { 21 return u==p[u]? u:p[u]=ifind(p[u]); 22 } 23 void unit(int x,int y) { 24 x=ifind(x),y=ifind(y); if(x!=y) p[x]=y; 25 } 26 27 void read(int& x) { 28 char c=getchar(); int f=1; x=0; 29 while(!isdigit(c)){if(c=='-')f=-1; c=getchar();} 30 while(isdigit(c)) x=x*10+c-'0',c=getchar(); 31 x*=f; 32 } 33 int main() { 34 read(n),read(c); 35 for(int i=1;i<=n;i++) p[i]=i; 36 int x,y; 37 for(int i=1;i<=n;i++) { 38 read(x),read(y); 39 a[i].x=x+y,a[i].y=x-y; 40 } 41 sort(a+1,a+n+1); 42 S.insert((Node){INF,0}),S.insert((Node){-INF,0}); 43 int front=1; 44 for(int i=1;i<=n;i++) { 45 while(a[i].x-a[front].x>c) { 46 S.erase(S.lower_bound((Node){a[front].y,front})); 47 ++front; 48 } 49 it=S.lower_bound((Node){a[i].y,i}); 50 Node r=*it,l=*(--it); 51 if((LL)r.x-(LL)a[i].y<=c) unit(r.y,i); 52 if((LL)a[i].y-(LL)l.x<=c) unit(l.y,i); 53 S.insert((Node){a[i].y,i}); 54 } 55 for(int i=1;i<=n;i++) { 56 sum[ifind(i)]++; 57 if(sum[ifind(i)]==1) ans++; 58 } 59 for(int i=1;i<=n;i++) mx=max(mx,sum[i]); 60 printf("%d %d",ans,mx); 61 return 0; 62 }
posted on 2016-02-16 11:10 hahalidaxin 阅读(492) 评论(0) 编辑 收藏 举报