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。。。
View Code
一个非常巧妙的方法求曼哈顿距离:
如果原来坐标是(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
相关文章推荐
- bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集)
- bzoj 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集)
- [BZOJ1604] [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居
- [BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(multiset+并查集)
- bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 曼哈顿生成树
- bzoj1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 (曼哈顿距离 转 切比雪夫距离+并查集+set)
- bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居【切比雪夫距离+并查集+multiset】
- BZOJ 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居
- BZOJ 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Treap
- 【BZOJ】1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(set+并查集+特殊的技巧)
- bzoj1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居
- 【bzoj 1604】: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 set+并查集
- 【BZOJ】1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居
- 【bzoj1604】【Usaco2008 Open】Cow Neighborhoods (set+曼哈顿距离性质+并查集)奶牛的邻居
- 并查集+Set-BZOJ-1604-[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居
- 【bzoj1604】: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居
- [BZOJ1604] [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(好题)
- BZOJ 1604 [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 Treap
- bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(切比雪夫距离+multiset贪心+并查集)
- BZOJ 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居