题意:求最小生成树第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(最小生成树)题解的更多相关文章

  1. POJ3241 Object Clustering 曼哈顿最小生成树

    题意:转换一下就是求曼哈顿最小生成树的第n-k条边 参考:莫涛大神的论文<平面点曼哈顿最小生成树> /* Problem: 3241 User: 96655 Memory: 920K Ti ...

  2. 【Poj3241】Object Clustering

    Position: http://poj.org/problem?id=3241 List Poj3241 Object Clustering List Description Knowledge S ...

  3. POJ 3241 Object Clustering 曼哈顿最小生成树

    Object Clustering   Description We have N (N ≤ 10000) objects, and wish to classify them into severa ...

  4. poj 3241 Object Clustering (曼哈顿最小生成树)

    Object Clustering Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 2640   Accepted: 806 ...

  5. 【poj3241】 Object Clustering

    http://poj.org/problem?id=3241 (题目链接) MD被坑了,看到博客里面说莫队要写曼哈顿最小生成树,我就写了一个下午..结果根本没什么关系.不过还是把博客写了吧. 转自:h ...

  6. 【POJ 3241】Object Clustering 曼哈顿距离最小生成树

    http://poj.org/problem?id=3241 曼哈顿距离最小生成树模板题. 核心思想是把坐标系转3次,以及以横坐标为第一关键字,纵坐标为第二关键字排序后,从后往前扫.扫完一个点就把它插 ...

  7. POJ 3241 曼哈顿距离最小生成树 Object Clustering

    先上几个资料: 百度文库有详细的分析和证明 cxlove的博客 TopCoder Algorithm Tutorials #include <cstdio> #include <cs ...

  8. POJ 3241 Object Clustering(Manhattan MST)

    题目链接:http://poj.org/problem?id=3241 Description We have N (N ≤ 10000) objects, and wish to classify ...

  9. 老oj3444 && Pku3241 Object Clustering

    Description We have N (N ≤ 10000) objects, and wish to classify them into several groups by judgemen ...

随机推荐

  1. JS闭包中的循环绑定处理程序

    前几天工作中写前端js代码时,遇到了遍历元素给它添加单击事件.就是这个问题让我整整调了一个下午.最后还是下班回家,上网查资料才知道怎么解决的. (PS:之前也在<jQuery基础教程>第四 ...

  2. Java学习之路-Spring的HttpInvoker学习

    Hessian和Burlap都是基于HTTP的,他们都解决了RMI所头疼的防火墙渗透问题.但当传递过来的RPC消息中包含序列化对象时,RMI就完胜Hessian和Burlap了. 因为Hessian和 ...

  3. cube-ui的用法

    .安装:npm install cube-ui -S .修改 .babelrc:(添加到plugins中去) { "plugins": [ ["transform-mod ...

  4. 关于Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案

    在Ubuntu中,有时候运用sudo  apt-get install 安装软件时,会出现一下的情况 E: Could not get lock /var/lib/dpkg/lock - open ( ...

  5. 下载google play上最新版的apk

    注意,是下载最新版的方法,不是像很多网站下的是旧版本 http://techapple.net/2014/09/3-websites-directly-download-apk-google-play ...

  6. MongoDB3.x中添加用户和权限控制

    现在需要创建一个帐号,该账号需要有grant权限,即:账号管理的授权权限.注意一点,帐号是跟着库走的,所以在指定库里授权,必须也在指定库里验证(auth) ? 1 2 3 4 5 6 7 8 9 10 ...

  7. C#调用VP 包含素材

    VS2012 +VP9.0 ***************** 自己运行的时只要修改VP里面素材的路径即可 链接: https://pan.baidu.com/s/1J6Bc5FcBYLZLgqe30 ...

  8. 借root之名,行流氓之实,劝告,root需谨慎

    20160425++++++ 今日再回头看这篇文章,貌似有点偏激了一点,不过xda论坛上有个疑似kingroot开发团队的用户说明了kingroot确实对supersu做了限制,说是supersu在替 ...

  9. GetLastError函数

      错误代码各个位数的意义:GetLastError函数返回值!SetLastError可是设置这个错误代码. 位 31-30 29 28 27-16 15-0 内容 严重性 Micorsoft/ 客 ...

  10. VS2010/MFC编程入门之四十三(MFC常用类:CTime类和CTimeSpan类)

    上一节中鸡啄米讲了MFC常用类CString类的用法,本节继续讲另外两个MFC常用类-日期和时间类CTime类和CTimeSpan类. 日期和时间类简介 CTime类的对象表示的时间是基于格林威治标准 ...