POJ3241 Object Clustering(最小生成树)题解
题意:求最小生成树第K大的边权值
思路:
如果暴力加边再用Kruskal,边太多会超时。这里用一个算法来减少有效边的加入。
边权值为点间曼哈顿距离,那么每个点的有效加边选择应该是和他最近的4个象限方向的点。这里用一个树状数组维护以y-x为索引的y+x的值,然后这个数组所储存的就是一个点的第一象限方向的距离他最近的点。这样我们每次查找只要看(i,N)这个区间是否有一个点的距离比现在的更小(因为以y-x为索引,所以I>i就表示I这个点在i的第一象限方向)。最后每个方向的边都加完后,只要用Kruskal算法加边,加到第K就输出权值。
代码:
#include<queue>
#include<cstring>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
const int N = 10000+5;
const int INIT = 1061109567;
using namespace std;
int n,k,cnt,Id[N],v[N],f[N];//id为v值的id序号,v为储存以y-x为索引的y+x值
struct node{
int x,y,id;
friend bool operator < (node a,node b){
return a.x == b.x? a.y < b.y : a.x < b.x;
}
}p[N];
struct edge{
int u,v,w;
friend bool operator < (edge a,edge b) {
return a.w < b.w;
}
}e[N<<2];
int lowbit(int x){
return x&(-x);
}
void query(int id,int pos,int val){
pos += 1000;
int u = -1,ret = INT_MAX;
for(int i = pos;i < N;i += lowbit(i)){
if(v[i] < ret && v[i] != INIT){ //找曼哈顿距离最短的
ret = v[i];
u = Id[i];
}
}
if(u != -1){ //找到这种点就加一个边
e[cnt].u = id;
e[cnt].v = u;
e[cnt++].w = ret - val;
}
}
void update(int id,int pos,int val){ //id,y-x,y+x
pos += 1000;
for(int i = pos;i > 0;i -= lowbit(i)){
if(val < v[i]){//更换最佳选择
v[i] = val;
Id[i] = id;
}
}
}
int find(int x){
if(x == f[x]) return x;
else return f[x] = find(f[x]);
}
void kruskal(){
sort(e,e+cnt);
for(int i = 0;i < N;i++) f[i] = i;
int num = n;
for(int i = 0;i < cnt;i++){
int x = find(e[i].u);
int y = find(e[i].v);
if(x != y){
f[x] = f[y];
num--;
if(num == k){
printf("%d\n",e[i].w);
return;
}
}
}
}
void addEdge(){
memset(v,63,sizeof(v)); //v == 1061109567
sort(p,p+n);
for(int i = n-1;i >= 0;i--){
int index = p[i].y - p[i].x;
int val = p[i].y + p[i].x;
query(p[i].id,index,val);
update(p[i].id,index,val);
}
}
int main(){
cnt = 0;
scanf("%d%d",&n,&k);
for(int i = 0;i < n ;i++){
scanf("%d%d",&p[i].x,&p[i].y);
p[i].id = i;
}
addEdge();
for(int i = 0;i < n;i++) swap(p[i].x,p[i].y);
addEdge();
for(int i = 0;i < n;i++) p[i].y = -p[i].y;
addEdge();
for(int i = 0;i < n;i++) swap(p[i].x,p[i].y);
addEdge();
kruskal();
return 0;
}
POJ3241 Object Clustering(最小生成树)题解的更多相关文章
- POJ3241 Object Clustering 曼哈顿最小生成树
题意:转换一下就是求曼哈顿最小生成树的第n-k条边 参考:莫涛大神的论文<平面点曼哈顿最小生成树> /* Problem: 3241 User: 96655 Memory: 920K Ti ...
- 【Poj3241】Object Clustering
Position: http://poj.org/problem?id=3241 List Poj3241 Object Clustering List Description Knowledge S ...
- 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 ...
- 【poj3241】 Object Clustering
http://poj.org/problem?id=3241 (题目链接) MD被坑了,看到博客里面说莫队要写曼哈顿最小生成树,我就写了一个下午..结果根本没什么关系.不过还是把博客写了吧. 转自:h ...
- 【POJ 3241】Object Clustering 曼哈顿距离最小生成树
http://poj.org/problem?id=3241 曼哈顿距离最小生成树模板题. 核心思想是把坐标系转3次,以及以横坐标为第一关键字,纵坐标为第二关键字排序后,从后往前扫.扫完一个点就把它插 ...
- POJ 3241 曼哈顿距离最小生成树 Object Clustering
先上几个资料: 百度文库有详细的分析和证明 cxlove的博客 TopCoder Algorithm Tutorials #include <cstdio> #include <cs ...
- POJ 3241 Object Clustering(Manhattan MST)
题目链接:http://poj.org/problem?id=3241 Description We have N (N ≤ 10000) objects, and wish to classify ...
- 老oj3444 && Pku3241 Object Clustering
Description We have N (N ≤ 10000) objects, and wish to classify them into several groups by judgemen ...
随机推荐
- 2018/03/18 isset、empty、is_null的区别
在平常的工作中,判断一个值是否为空的情况时,会直接使用 if ($var) 这种形式,有时也会使用这三个函数进行比较,但是当时也没有很深入的学习. -- 还是通过实例来判断这几个的用法和场景 首先定义 ...
- servlet输出请求头
1.参考 Enumeration headerNames = req.getHeaderNames(); while(headerNames.hasMoreElements()) { String h ...
- 【剑指offer】重建二叉树
一.题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7 ...
- delete删除-some
- [py][mx]django注册-邮件激活
人生,学习,就是一段旅途, 说是放弃,其实是自信心作祟. 因为不同时间段状态,譬如晚上和早上刚来状态不一样.做相同事情容器失去自信而放弃. 坚持可以打破这个魔咒 还有就是有些问题得分割, 不要让压死牛 ...
- Python中如何获取类属性的列表
这篇文章主要给大家介绍了在Python中如何获取类属性的列表,文中通过示例代码介绍的很详细,相信对大家的学习或者工作具有一定的参考借鉴价值,有需要的朋友可以参考借鉴,下面来一起看看吧. 前言 最近工作 ...
- PAT 1067 Sort with Swap[难]
1067 Sort with Swap(0,*) (25)(25 分) Given any permutation of the numbers {0, 1, 2,..., N-1}, it is e ...
- JS的二维数组
今天,记录一下JS的二位数组,并附上例题. 一.二维数组的本质:数组中的元素又是数组. 其实,我们都见过这样的二维数组,只不过没在意罢了,例如: var arr = [[1,2,4,6],[2,4,7 ...
- libsvm使用
先挖个坑,有空重写svm_scale, svm_train, svm_predict几个代码,给的实在写的不敢恭维 package org.ml.svm; import java.io.File; i ...
- python-计算器实现
# 开发一个简单的python计算器# 实现加减乘除及括号优先级解析# 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * ...