您的位置:首页 > 运维架构

BZOJ1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居

2014-10-22 11:03 513 查看
BZOJ200题纪念!

一个非常巧妙的方法求曼哈顿距离:

如果原来坐标是(x, y),令新的坐标为(X, Y), 其中X = x + y, Y = x - y

那么:曼哈顿距离 = |x1 - x2| + |y1 - y2| = max(|X1 - X2|, |Y1 - Y2|)

于是我们先进行坐标变换,按X排序。

然后用一个队列来做,满足队尾X - 队首X < c。

对这个队列中每个点的Y维护一棵平衡树,如果新加入元素的前驱后继与它的Y值差值不超过c,则用并查集将他们连在一起。

(其实就是类似kruskal的改进版本)

蒟蒻不会平衡树,于是又使用了STL的multiset。。。

/**************************************************************
Problem: 1604
User: rausen
Language: C++
Result: Accepted
Time:868 ms
Memory:5396 kb
****************************************************************/

#include <cstdio>
#include <algorithm>
#include <set>

using namespace std;
typedef long long ll;
const ll inf = (ll) 1e16;
const int N = 100005;

struct data{
ll x, y;
int w;
}a
;
inline bool operator < (const data &a, const data &b){
return a.y < b.y;
}
inline bool cmpx (const data &a, const data &b){
return a.x < b.x;
}

int fa
, cnt
, ans, ANS;
int n, c, X, Y;
multiset <data> S;
set <data> ::iterator it;

int x;
char ch;
inline unsigned int read(){
x = 0;
ch = getchar();
while (ch < '0' || ch > '9')
ch = getchar();

while (ch >= '0' && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x;
}

int find_fa(int x){
return fa[x] == x ? x : fa[x] = find_fa(fa[x]);
}

inline void Union(int x, int y){
x = find_fa(x), y = find_fa(y);
if (x != y)
fa[x] = y, --ans;
}

void work(){
for (int i = 1; i <= n; ++i)
fa[i] = i;
S.insert((data) {0, inf, 0});
S.insert((data) {0, -inf, 0});
S.insert(a[1]);
int now = 1;
data l, r;
for (int i = 2; i <= n; ++i){
while (a[i].x - a[now].x > c)
S.erase(S.find(a[now++]));
it = S.lower_bound(a[i]);
r = *it, l = *--it;
if (a[i].y - l.y <= c)
Union(a[i].w, l.w);
if (r.y - a[i].y <= c)
Union(a[i].w, r.w);
S.insert(a[i]);
}
}

int main(){
n = read(), c = read(), ans = n;
for (int i = 1; i <= n; ++i){
X = read(), Y = read();
a[i].x = X + Y, a[i].y = X - Y, a[i].w = i;
}
sort(a + 1, a + n + 1, cmpx);

work();
for (int i = 1; i <= n; ++i)
++cnt[find_fa(i)];
for (int i = 1; i <= n; ++i)
ANS = max(ANS, cnt[i]);
printf("%d %d\n", ans, ANS);
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐