转自:https://www.cnblogs.com/Anding-16/p/7367845.html

POJ-3241 Object Clustering

Dscription

We have (N ≤ 10000) objects, and wish to classify them into several groups by judgement of their resemblance. To simply the model, each object has 2 indexes a and b (ab ≤ 500). The resemblance of object i and object j is defined by dij = |ai - aj| + |bi - bj|, and then we say i is dij resemble to j. Now we want to find the minimum value of X, so that we can classify the N objects into K (< N) groups, and in each group, one object is at most X resemble to another object in the same group, i.e, for every object i, if i is not the only member of the group, then there exists one object j (i ≠ j) in the same group that satisfies dij ≤ X

Input

The first line contains two integers N and K. The following N lines each contain two integers a and b, which describe a object.

Output

A single line contains the minimum X.

Sample Input

6 2
1 2
2 3
2 2
3 4
4 3
3 1

Sample Output

2

[Submit]   [Status]   [Discuss]

 

- 题意 -

 曼哈顿距离最小生成树上第k大的边.
 曼哈顿距离: (对于点A(x1, y1), B(x2, y2))
 dis(A,B)=|x1−x2|+|y1−y2| dis(A,B)=|x1−x2|+|y1−y2| .
 (下文中dis() dis() , 距离均指曼哈顿距离)
 (下文中dis() dis() , 距离均指曼哈顿距离)
 (下文中dis() dis() , 距离均指曼哈顿距离)
 

- 思路 -

 参考题解:  http://blog.csdn.net/huzecong/article/details/8576908
 
 直接暴力的话会有N 2  N2 条边, 总复杂度O(N 2 logN)(N≤10000) O(N2logN)(N≤10000) .
 果断爆炸.
 我们可以删去一些无用边.
 
 对于一个平面上的点 i(x i ,y i ) i(xi,yi) , 我们以它为中心把周围部分为8份.
 
 
 考虑每一份中最多有一个点与点 i 相连, 如 R1:
 
 
 设此时点A是与点 i 距离最小的点, 则为点A, i建一条边, 考虑该部分的其它点(如点B), 它们与 A 的距离显然小于与 i 的距离(如dis(A,B)<dis(i,B) dis(A,B)<dis(i,B) ), 所以其它点与 A 连边优于i.
 以上图三个点为例, 用两条边将它们联通的最小代价W=dis(i,A)+dis(A,B)≤dis(i,A)+dis(i,B) W=dis(i,A)+dis(A,B)≤dis(i,A)+dis(i,B)
 dis(i,A)+dis(A,B)=dis(i,A)+dis(i,B) dis(i,A)+dis(A,B)=dis(i,A)+dis(i,B) 的情况如下:(A−B A−B 连线垂直于A−i A−i 连线)
 
 所以对于每个点每一份中只需要连一条边, 由于边是无向的, 我们可以只连向右的边(也就是R1-4内的点, 点 i 向左的连线由左边的点来连), 这样就只有N*4条边了.
 继续分析R1的情况, 如何找到 A 点.
 发现首先 R1 区间内的点 k 满足 :
   X i ≤X k  Xi≤Xk
   X k −X i ≤Y k −Y i  Xk−Xi≤Yk−Yi 即 Y i −X i ≤Y k −X k  Yi−Xi≤Yk−Xk (k为R1内任一点)
 我们在满足条件的点中找到X+Y X+Y 最小的节点就行了.
 于是我们可以维护一个树状数组(线段树), 底层按离散化后的Y−X Y−X 排序, 维护区间内X+Y X+Y 的最小值,
按照先从右到左, 再从上到下的顺序插入节点并查找.
 对于R2-4三个部分, 我们可以对点进行旋转, 将它们转换为 R1 内的点.
 
 (注意看原先的R1的位置依次有R2, R3, R4的点, 这样就可以连出四个部分的边了)
 
 细节见代码.
 

- 代码 -

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;const int N = 1e5 + 5;
const int inf = 0x3f3f3f3f;struct edge
{int x, y, v;bool operator < (const edge &tmp) const{return v < tmp.v;}
} E[N<<3];struct point
{int x, y, id;bool operator < (const point &tmp) const{return x == tmp.x ? y < tmp.y : x < tmp.x;}
} P[N];struct lsh
{int id, a;bool operator < (const lsh &tmp) const{return a < tmp.a;/*     if (a == tmp.a) return id < tmp.id;return a < tmp.a;*/}
} LSH[N];int A[N], F[N];
int MI[N], ID[N];
int n, c, sz, tot, cnt;int lowbit (int x)
{return x&(-x);
}int query(int x)
{int ans = -1, mi = inf;for (; x <= n; x += lowbit(x))if (MI[x] < mi){mi = MI[x];ans = ID[x];}return ans;
}void modify(int x, int mi, int id)
{for (; x > 0; x -= lowbit(x))if (MI[x] > mi){MI[x] = mi;ID[x] = id;}
}
//BIT维护的是某数字代表的区间的X+Y最小值, 若一区间的不同位置最小值不同, 该区间则没有最小值(即MI数组维护的是其表示的区间都可以取到的最小值)
int find(int x)
{return F[x] == x ? x : F[x] = find(F[x]);
}void join(int x, int y)
{int fx = find(x), fy = find(y);if (fx == fy) return;F[fx] = fy;cnt++;
}void init ()
{sort(P + 1, P + n + 1);for (int i = 1; i <= n; ++i){LSH[i].a = P[i].y - P[i].x;LSH[i].id = i;MI[i] = inf;ID[i] = -1;}
}int abs(int x, int y)
{return x > 0 ? x : -x;
}int dts(int x, int y)
{return abs(P[x].x - P[y].x) + abs(P[x].y  -P[y].y);
}void add_edge (int x, int y, int d)
{E[++sz].x = x;E[sz].y = y;E[sz].v = d;
}int main()
{scanf("%d%d", &n, &c);for (int i = 1; i <= n; ++i){scanf("%d%d", &P[i].x, &P[i].y);P[i].id = i;}for (int cas = 1; cas <= 4; ++cas){if (cas == 2 || cas == 4)for (int i = 1; i <= n; ++i)swap(P[i].x, P[i].y);if (cas == 3)for (int i = 1; i <= n; ++i)P[i].x = -P[i].x;init();sort(LSH + 1, LSH + n + 1);//按Y-X离散化for (int i = 1; i <= n; ++i)A[LSH[i].id] = i; //A表示某点在BIT中的位置for (int i = n; i >= 1; --i){int tmp = query(A[i]);if (tmp != -1)add_edge(P[tmp].id, P[i].id, dts(tmp, i));modify(A[i], P[i].x + P[i].y, i);}}for (int i = 1; i <= n; ++i) F[i] = i;sort(E + 1, E + sz + 1);for (int i = 1; i <= sz; ++i){join(E[i].x, E[i].y);if (cnt == n - c){printf("%d\n", E[i].v);break;}}return 0;
}

曼哈顿距离最小生成树(树状数组)相关推荐

  1. 51nod 1213 二维曼哈顿距离最小生成树 树状数组+最小生成树

    Description 二维平面上有N个坐标为整数的点,点x1 y1同点x2 y2之间的距离为:横纵坐标的差的绝对值之和,即:Abs(x1 - x2) + Abs(y1 - y2)(也称曼哈顿距离). ...

  2. 曼哈顿距离最小生成树

    一.参考博客 博客:曼哈顿距离最小生成树与莫队算法 博客:学习总结:最小曼哈顿距离生成树 二.前置知识 1.曼哈顿距离:给定二维平面上的N个点,在两点之间连边的代价.(即distance(P1,P2) ...

  3. 曼哈顿距离最小生成树与莫队算法(总结)

    曼哈顿距离最小生成树与莫队算法(总结) 1 曼哈顿距离最小生成树 曼哈顿距离最小生成树问题可以简述如下:  给定二维平面上的N个点,在两点之间连边的代价为其曼哈顿距离,求使所有点连通的最小代价.  朴 ...

  4. 图论 —— 生成树 —— 曼哈顿距离最小生成树

    [概述] 当给出一些二维平面的点时,记两点间距离为曼哈顿距离,此时的最小生成树,称为曼哈顿最小距离生成树. 对于 n 个点来说,最朴素的做法是暴力求出所有所有点两两之间的曼哈顿距离,然后再跑最小生成树 ...

  5. 曼哈顿距离最小生成树莫队算法

    参考资料:https://www.cnblogs.com/CsOH/p/5904430.html https://blog.csdn.net/huzecong/article/details/8576 ...

  6. 51nod 1213 二维曼哈顿距离最小生成树

    1213 二维曼哈顿距离最小生成树 基准时间限制:4 秒 空间限制:131072 KB 分值: 160 难度:6级算法题  收藏  关注 二维平面上有N个坐标为整数的点,点x1 y1同点x2 y2之间 ...

  7. 2018东北四省赛 Spin A Web 曼哈顿距离最小生成树

    莫队的论文,讲的很清晰 问题描述:给定平面N个点,两边相连的代价为曼哈顿距离,求这些点的最小生成树 按一般想法,prime复杂度O(n^2),Kruskal复杂度O(n^2 logn),N很大时,这复 ...

  8. 曼哈顿距离最小生成树与莫队算法

    一.曼哈顿距离最小生成树 曼哈顿距离最小生成树问题可以简述如下: 给定二维平面上的N个点,在两点之间连边的代价为其曼哈顿距离,求使所有点连通的最小代价. 朴素的算法可以用O(N2)的Prim,或者处理 ...

  9. HDU-4456 Crowd 二维树状数组+坐标转换

    题意:给定一个N*N的网格,现在M组操作,一种操作时改变网格上的某个单点的权值,另外一种操作是求到一点曼哈顿距离为小于等于k的所有的权值和,初始化网格所有点的权值为0. 解法:这题如果没有那些特定的条 ...

  10. 金色丝线将瞬间一分为二 树状数组的使用

    Description 为了解开骑士木乃伊事件,久城一弥和布洛瓦警官来到了停尸间.停尸间里有N具遗体,每具遗体都有一个坐标(X,Y). 由于停尸间的遗体摆放得横平竖直,我们认为两具遗体(Xi,Yi)和 ...

最新文章

  1. 查看anaconda所用python安装路径conda info --env
  2. PyQt5 笔记5 -- 消息框(QMessageBox)
  3. [Python图像处理] 十四.基于OpenCV和像素处理的图像灰度化处理
  4. 给网游写一个挂吧(二) – 启动外挂上
  5. C#使用Redis的基本操作
  6. 连载:面向对象葵花宝典:思想、技巧与实践(32) - LSP原则
  7. GitHub 和GitLab的开发工具使用
  8. Struts的增删改查
  9. edge播放视频HTML5黑屏,edge不能播放网页视频怎么办-修复edge浏览器播放视频黑屏的方法 - 河东软件园...
  10. 纹理压缩格式DXT/PVR/ETC编码
  11. matlab 此上下文中不允许函数定义,错误: 此上下文中不允许函数定义。怎么办
  12. php发送消息给telegram,PHP对接telegram
  13. Discuz x2 数据字典
  14. 手把手教-在自己的服务器上运行psychopy线上实验
  15. imgaug数据增强库使用
  16. 进程和线程的区别 进程间的通信方式
  17. 机器学习入门-西瓜书总结笔记第十五章
  18. vue-barcode生成条形码
  19. 搜索引擎与爬虫结合的示例:书虫找书
  20. [Deconv]|[cnn]Deep visualization toolbox安装

热门文章

  1. STRAIGHT分析合成算法
  2. 删除联想硬盘OEM分区——最简单方法
  3. 浅谈一类积性函数的前缀和
  4. Vue实战篇三十四:给新闻WebApp加入模拟注册登录功能
  5. Bypass Windows AppLocker
  6. 没错,我在用JBOD,它真的很好
  7. arp在交换机级联情况下的访问
  8. 微信小程序、公众号侵权投诉流程
  9. True Liars (POJ - 1417)带权并查集+dp路径
  10. 网站安全公司对渗透测试行业的运营观点