[BZOJ1604] [Usaco2008 Open] Cow Neighborhoods 奶牛的邻居 (queue & 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
Solution
设点$(x',y')$表示$(x+y,x-y)$,则:
有这样一个性质:两个点的曼哈顿距离为$max(|x'_1-x'_2|,|y'_1-y'_2|)$
所以先将所有点预处理,之后按$x'$坐标排序。
用一个队列维护$x'$使队列里所有元素$x'$之差不超过$C$,用set维护$y'$
若新插入元素的前驱或后继与该元素之差小于等于$C$就用并查集把它们连起来
数一下联通块的个数就行了。
1 #include <bits/stdc++.h> 2 #define fir first 3 #define sec second 4 #define mp make_pair 5 using namespace std; 6 typedef pair<int, int> pii; 7 const int INF = 2100000000; 8 set<pii> S; 9 set<pii>::iterator it; 10 queue<int> Q; 11 pii a[100005]; 12 int fa[100005], siz[100005]; 13 14 int getfa(int x) 15 { 16 return fa[x] = x == fa[x] ? x : getfa(fa[x]); 17 } 18 19 int main() 20 { 21 int n, c, u, v, cnt = 0, mx = 1; 22 cin >> n >> c; 23 for(int i = 1; i <= n; i++) 24 { 25 cin >> a[i].fir >> a[i].sec; 26 a[i].fir += a[i].sec; 27 a[i].sec = a[i].fir - 2 * a[i].sec; 28 fa[i] = i; 29 } 30 sort(a + 1, a + n + 1); 31 S.insert(mp(-INF, 0)), S.insert(mp(INF, 0)); 32 Q.push(1), S.insert(mp(a[1].sec, 1)); 33 for(int i = 2; i <= n; i++) 34 { 35 while(!Q.empty() && a[i].fir - a[Q.front()].fir > c) 36 { 37 u = Q.front(), Q.pop(); 38 S.erase(mp(a[u].sec, u)); 39 } 40 it = S.lower_bound(mp(a[i].sec, 0)); 41 if(it->sec && it->fir - a[i].sec <= c) 42 { 43 u = getfa(it->sec), v = getfa(i); 44 if(u != v) fa[u] = v; 45 } 46 if((--it)->sec && a[i].sec - it->fir <= c) 47 { 48 u = getfa(it->sec), v = getfa(i); 49 if(u != v) fa[u] = v; 50 } 51 Q.push(i), S.insert(mp(a[i].sec, i)); 52 } 53 for(int i = 1; i <= n; i++) 54 { 55 if(++siz[getfa(i)] == 1) cnt++; 56 mx = max(mx, siz[getfa(i)]); 57 } 58 cout << cnt << ' ' << mx << endl; 59 return 0; 60 }