【POJ 3241】Object Clustering 曼哈顿距离最小生成树
http://poj.org/problem?id=3241
曼哈顿距离最小生成树模板题。
核心思想是把坐标系转3次,以及以横坐标为第一关键字,纵坐标为第二关键字排序后,从后往前扫。扫完一个点就把它插到树状数组的y-x位置上,权值为x+y。查询时查询扫过的所有点满足ydone-xdone>=ynow-xnow时,直接是树状数组中的的一个后缀区间,从后往前扫保证了区间内的这些点都在当前点的y轴向右扫45度的范围内。树状数组实现查询x+y的最小值,以及此最小值对应原数组中的位置,方便建图连边。
模板是抄的别人的QAQ
时间复杂度$O(n\log n)$
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100003;
int in() {
int k = 0, fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = (k << 3) + (k << 1) + c - '0';
return k * fh;
} struct Point {
int x, y, id;
bool operator < (const Point &A) const {
return x == A.x ? y < A.y : x < A.x;
}
} P[N];
struct Bits {
int mn, pos;
void init() {mn = 0x7fffffff; pos = -1;}
} bit[N];
int tot;
struct Edge {
int u, v, dis;
bool operator < (const Edge &A) const {
return dis < A.dis;
}
} E[N << 2];
void add(int a, int b, int c) {E[++tot] = (Edge) {a, b, c};} int n, fa[N], k;
int find(int x) {
if (fa[x] == x) return x;
fa[x] = find(fa[x]); return fa[x];
} int dist(int x, int y) {
return abs(P[x].x - P[y].x) + abs(P[x].y - P[y].y);
} void update(int x, int num, int pos) {
for(; x; x -= (x & (-x)))
if (num < bit[x].mn)
bit[x].mn = num, bit[x].pos = pos;
} int m;
int query(int x) {
int ans = 0x7fffffff, pos = -1;
for(x; x <= m; x += (x & (-x)))
if (bit[x].mn < ans)
ans = bit[x].mn, pos = bit[x].pos;
return pos;
} int a[N], H[N], cnt;
int solve() {
for(int change = 0; change < 4; ++change) {
if (change == 1 || change == 3)
for(int i = 1; i <= n; ++i) swap(P[i].x, P[i].y);
else if (change == 2)
for(int i = 1; i <= n; ++i) P[i].x = -P[i].x; sort(P + 1, P + n + 1);
for(int i = 1; i <= n; ++i)
a[i] = H[i] = P[i].y - P[i].x;
cnt = n;
sort(H + 1, H + cnt + 1);
cnt = unique(H + 1, H + cnt + 1) - H;
for(int i = 1; i <= cnt; ++i) bit[i].init();
int pos, tmp; m = cnt;
for(int i = n; i > 0; --i) {
pos = lower_bound(H + 1, H + cnt, a[i]) - H;
tmp = query(pos);
if (tmp != -1)
add(P[i].id, P[tmp].id, dist(i, tmp));
update(pos, P[i].x + P[i].y, i);
}
}
sort(E + 1, E + tot + 1);
cnt = n - k;
for(int i = 1; i <= n; ++i) fa[i] = i;
int u, v;
for(int i = 1; i <= tot; ++i) {
u = find(E[i].u); v = find(E[i].v);
if (u != v) {
--cnt;
fa[u] = v;
if (cnt == 0) return E[i].dis;
}
}
} int main() {
while (~scanf("%d%d", &n, &k)) {
tot = 0;
for(int i = 1; i <= n; ++i) {
P[i].x = in(); P[i].y = in();
P[i].id = i;
}
printf("%d\n", solve());
}
return 0;
}

【POJ 3241】Object Clustering 曼哈顿距离最小生成树的更多相关文章
- POJ 3241 Object Clustering 曼哈顿最小生成树
Object Clustering Description We have N (N ≤ 10000) objects, and wish to classify them into severa ...
- poj 3241 Object Clustering (曼哈顿最小生成树)
Object Clustering Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 2640 Accepted: 806 ...
- POJ 3241Object Clustering曼哈顿距离最小生成树
Object Clustering Description We have N (N ≤ 10000) objects, and wish to classify them into several ...
- POJ 3241 Object Clustering(Manhattan MST)
题目链接:http://poj.org/problem?id=3241 Description We have N (N ≤ 10000) objects, and wish to classify ...
- 51nod 1213 二维曼哈顿距离最小生成树
1213 二维曼哈顿距离最小生成树 基准时间限制:4 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 收藏 关注 二维平面上有N个坐标为整数的点,点x1 y1同点x2 y2之间 ...
- 曼哈顿距离最小生成树 codechef Dragonstone
曼哈顿距离最小生成树 codechef Dragonstone 首先,对于每一个点来说有用的边只有它向它通过 x=0,y=0,y=x,y=-x 切出来的八个平面的最近点. 证明 我不会 反正当结论记住 ...
- [51nod1213]二维曼哈顿距离最小生成树
二维平面上有N个坐标为整数的点,点x1 y1同点x2 y2之间的距离为:横纵坐标的差的绝对值之和,即:Abs(x1 - x2) + Abs(y1 - y2)(也称曼哈顿距离).求这N个点所组成的完全图 ...
- POJ 3241 曼哈顿距离最小生成树 Object Clustering
先上几个资料: 百度文库有详细的分析和证明 cxlove的博客 TopCoder Algorithm Tutorials #include <cstdio> #include <cs ...
- POJ3241 Object Clustering 曼哈顿最小生成树
题意:转换一下就是求曼哈顿最小生成树的第n-k条边 参考:莫涛大神的论文<平面点曼哈顿最小生成树> /* Problem: 3241 User: 96655 Memory: 920K Ti ...
随机推荐
- 强加密RNGCryptoServiceProvider
.net RNGCryptoServiceProvider 对应 java SecureRandom public class SecureRandomextends Random This cla ...
- guava 学习笔记 使用瓜娃(guava)的选择和预判断使代码变得简洁
guava 学习笔记 使用瓜娃(guava)的选择和预判断使代码变得简洁 1,本文翻译自 http://eclipsesource.com/blogs/2012/06/06/cleaner-code- ...
- poj1001 Exponentiation 大数的幂
Description Problems involving the computation of exact values of very large magnitude and precision ...
- oracle基本用法
作为企业版的后台数据支撑,就首先要掌握oracle的使用方法!!! 注册用户之前,需要使用system管理员来进行注册功能!!! 1.首先创建新用户 2.这样就能使创建的新用户能够登陆吗?不,还需要分 ...
- MySQL 基础语句的练习
-- *** ①.对数据库的操作 *** -- -- 查看所有的数据库 SHOW DATABASES; -- 创建数据库 CREATE DATABASE day1026 DEFAULT CHARACT ...
- 10 Things Every Java Programmer Should Know about String
String in Java is very special class and most frequently used class as well. There are lot many thin ...
- 在windows下安装配置Ulipad
在windows下安装配置Ulipad 今天推荐一款轻便的文本编辑器Ulipad,用来写一些小的Python脚本非常方便. Ulipad下载地址: https://github.com/limodou ...
- 解决Kafka-1194问题
生产环境中使用Kafka作为日志处理的中间件,系统结构是这样的.自12月上线一个多月来,系统运行稳定. 用过kafka的都知道,Kafka产生的消息全部存储到硬盘文件中,并且在消息被消费后不会被立即删 ...
- SQL基础之select
1.认识select select的主要语法如下,这个很重要因为只有记住了整体的结构才能应对任何情况.从中可以看到select的强大主要就是建立在where.group by.having.order ...
- .Net Core+cenos7+Docker+Dockerfile 部署实践
因为这段时间比较忙,同时也在抽时间将开发框架转移到 .net Core 上 所以写博客的时间就少了,这次我利用dockerfile成功将.net Core程序部署到了cenos7容器中,特抽时间把我的 ...