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 ...
随机推荐
- Git使用常见问题脚本
receive.denyCurrentBranch 这是由于git默认拒绝了push操作,需要进行设置,修改.git/config添加如下代码: [receive] denyCurrentBr ...
- table的td的1%
使用media-obj和media-bd类似的样式,大多数采用的是display: table-cell(即是table中td)来实现.当然设置display是不够,还要根据情况设置width.如下面 ...
- 自增ID时如何插入ID
自增ID时如何插入ID SET IDENTITY_INSERT TABLE_NAME ON; INSERT INTO TABLE_NAME(XXX, XXX,..., XXX) SELECT XXX, ...
- word 加载adobe acrobat ,保存word中的清晰图片
1:先安装 adobe 并激活 https://blog.csdn.net/xintingandzhouyang/article/details/82558235 2:打开word,点击 文件&g ...
- [py]django前台处理后端返回的各类数据
参考 要完成的任务 返回str 返回list 返回arr 前端遍历 关键字 if for语句处理str list dict - 遍历字典 for语句 {% for key, value in info ...
- ZOJ:2833 Friendship(并查集+哈希)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2833 A friend is like a flower, a rose ...
- <span> 标签
<span> 标签被用来组合文档中的行内元素. 如果不对 span 应用样式,那么 span 元素中的文本 与 其他文本不会有任何视觉上的差异.尽管如此,上例中的 span 元素仍然为 p ...
- [LeetCode] 627. Swap Salary_Easy tag: SQL
Given a table salary, such as the one below, that has m=male and f=female values. Swap all f and m v ...
- Django-form组件和ModelForm组件
一. 构建Form表单 通过建一个类,添加需要进行验证的form字段,继而添加验证条件 from django import forms from django.forms import widget ...
- matplotlib显示中文
[注意] 可能与本文主题无关,不过我还是想指出来:使用matplotlib库时,下面两种导入方式是等价的(我指的是等效,当然这个说法可以商榷:) import matplotlib.pyplot as ...