题意:转换一下就是求曼哈顿最小生成树的第n-k条边

参考:莫涛大神的论文《平面点曼哈顿最小生成树》

/*
Problem: 3241 User: 96655
Memory: 920K Time: 94MS
Language: C++ Result: Accepted
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long LL;
const int maxn=;
const int INF=0x3f3f3f3f;
const int maxm=;
int n,k,p;
struct Point
{
int x,y,id;
bool operator<(const Point &e)const
{
if(x==e.x)return y<e.y;
return x<e.x;
}
} point[maxn];
struct Edge
{
int u,v,w;
bool operator<(const Edge &e)const
{
return w<e.w;
}
} edge[maxn*];
void addedge(int a,int b,int l,int r)
{
++p;
edge[p].u=a;
edge[p].v=b;
edge[p].w=abs(l-r);
}
struct Node
{
int len,id;
} node[(maxm+)<<];
void pushup(int rt)
{
node[rt].len=min(node[rt*].len,node[rt*+].len);
if(node[rt].len==node[rt*].len)node[rt].id=node[rt*].id;
else node[rt].id=node[rt*+].id;
}
void change(int rt,int l,int r,Point tt)
{
if(l==r)
{
node[rt].len=tt.x+tt.y;
node[rt].id=tt.id;
return;
}
int pos=tt.y-tt.x+;
int m=(l+r)>>;
if(pos<=m)change(rt*,l,m,tt);
else change(rt*+,m+,r,tt);
pushup(rt);
}
Node query(int rt,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
return node[rt];
int m=(l+r)>>;
if(y<=m)return query(rt*,l,m,x,y);
else if(x>m)return query(rt*+,m+,r,x,y);
else
{
Node t1,t2;
t1=query(rt*,l,m,x,y);
t2=query(rt*+,m+,r,x,y);
if(t1.len<t2.len)return t1;
else return t2;
}
}
int fa[maxn];
int find(int x)
{
if(x==fa[x])return x;
return fa[x]=find(fa[x]);
}
void init()
{
for(int i=; i<(maxm<<); ++i)
node[i].len=INF,node[i].id=-;
}
void build()
{
sort(point+,point++n);
init();
for(int i=n; i>; --i)
{
int s=point[i].x+point[i].y;
Node t=query(,,maxm,point[i].y-point[i].x+,maxm);
if(t.id!=-)
addedge(point[i].id,t.id,s,t.len);
change(,,maxm,point[i]);
} }
int solve()
{
sort(edge+,edge+p+);
int cnt=;
for(int i=; i<=p; ++i)
{
int fx=find(edge[i].u);
int fy=find(edge[i].v);
if(fx!=fy)
{
fa[fy]=fx;
++cnt;
if(cnt==n-k)return edge[i].w;
}
}
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=; i<=n; ++i)
scanf("%d%d",&point[i].x,&point[i].y),point[i].id=i;
for(int i=; i<=n; ++i)
fa[i]=i;
p=;
build();
for(int i=; i<=n; ++i)
point[i].y=-point[i].y;
build();
for(int i=; i<=n; ++i)
point[i].y=-point[i].y,swap(point[i].x,point[i].y);
build();
for(int i=; i<=n; ++i)
point[i].y=-point[i].y;
build();
printf("%d\n",solve());
return ;
}

POJ3241 Object Clustering 曼哈顿最小生成树的更多相关文章

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

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

  2. POJ3241 Object Clustering(最小生成树)题解

    题意:求最小生成树第K大的边权值 思路: 如果暴力加边再用Kruskal,边太多会超时.这里用一个算法来减少有效边的加入. 边权值为点间曼哈顿距离,那么每个点的有效加边选择应该是和他最近的4个象限方向 ...

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

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

  4. 【Poj3241】Object Clustering

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

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

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

  6. 【poj3241】 Object Clustering

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

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

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

  8. 【BZOJ-2177】曼哈顿最小生成树 Kruskal + 树状数组

    2177: 曼哈顿最小生成树 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 190  Solved: 77[Submit][Status][Discu ...

  9. BZOJ 2177: 曼哈顿最小生成树

    Sol 考了好几次曼哈顿最小生成树,然而一直不会打...这次终于打出来了...神tm调试了2h...好蛋疼... 首先曼哈顿最小生成树有个结论就是讲它每45度分出一个象限,对于每个点,只与每个象限中离 ...

随机推荐

  1. 关于java中sizeof的问题

    因为java没有提供现成的函数去计算对象的内存空间,不过可以用大量产生某个对象然后计算平均值的方法近似获得该对象占用的内存. 虽然这种方法不是很准,但是也在一定程度上计算出来了对象所占用的内存空间,下 ...

  2. c#类库中使用Session

    网站开发中,为了保存用户的信息,有时候需要使用session.如果我们在aspx页面中使用Session,只需要Session["key"]=value就可以,获取时使用int u ...

  3. cmp比较指令对标志寄存器的影响

    比如: mov ax,x mov bx,y cmp ax,bx cmp ax,bx的逻辑含义是比较ax,bx中的值.如果执行后: ZF=1则AX=BX ZF=0则AX!=BX CF=1则AX<B ...

  4. c++中的隐藏、重载、覆盖(重写)

    转自c++中的隐藏.重载.覆盖(重写) 1 重载与覆盖 成员函数被重载的特征: (1)相同的范围(在同一个类中): (2)函数名字相同: (3)参数不同: (4)virtual关键字可有可无. 覆盖是 ...

  5. Cloud Insight 和 BearyChat 第一次合体,好紧张!

    说到 ChatOps 我们可能立刻想到是 Slack(啥?没听过?哦!),但是由于国内网络和语言的问题你可能无法拥有很好的体验了.那就把目光转回国内吧,国内的话就不得不提到 BearyChat 等 C ...

  6. Java 程序检查远程服务器状态

    通常我们以命令的方式判断远程服务器是否正常运行有两种方式,ping 或 telnet 一个远程端口.假设我们要检查的远程服务器都是 Linux 系统. 从 JDK 1.5 以后, InetAddres ...

  7. weak_ptr的一点认识

    近期在补充和梳理C++方面的知识的时候,遇到了WeakPtr这个概念和用法,不甚明白,Google出了一堆文字,包括Boost的shared_ptr和weak_ptr的比较,以及其他一些博客里面给的例 ...

  8. 阿里云,CentOS下yum安装mysql,jdk,tomcat

    首先说明,服务器是阿里云的,centos6.3_64位安全加固版.首先需要登陆进来,使用的是putty,因为最初的时候,Xshell登陆会被拒绝. 0. 创建个人文件夹 # 使用 yum 安装tomc ...

  9. Google Play市场考察报告-2

    接上文,本次继续考察App. (6)CNBETA win8平板客户端 cnBeta是国内少有的科技类资讯网站,在程序员群体中具有很大影响力.面向程序员的软件应用在APP中一向属于少数,然而程序员群体已 ...

  10. SQLite入门与分析(四)---Page Cache之事务处理(2)

    写在前面:个人认为pager层是SQLite实现最为核心的模块,它具有四大功能:I/O,页面缓存,并发控制和日志恢复.而这些功能不仅是上层Btree的基础,而且对系统的性能和健壮性有关至关重要的影响. ...