基准时间限制:4 秒 空间限制:131072 KB 分值: 160 难度:6级算法题
 收藏
 关注
二维平面上有N个坐标为整数的点,点x1 y1同点x2 y2之间的距离为:横纵坐标的差的绝对值之和,即:Abs(x1 - x2) + Abs(y1 - y2)(也称曼哈顿距离)。求这N个点所组成的完全图的最小生成树的边权之和。

Input
第1行:1个数N,表示点的数量。(2 <= N <= 50000)
第2 - N + 1行:每行2个数,表示点的坐标(0 <= x, y <= 1000000)
Output
输出N个点所组成的完全图的最小生成树的边权之和。
Input示例
3
0 0
1 0
1 1
Output示例
2

所以我们只要求一个点在其45°角的区域内离他最近的点就行了,而这可以用线段树或树状数组解决

我们以y轴正半轴往右偏45°角的区域为例:

点j在点i的这个区域要满足的条件是:

yj-xj>yi-xi

且xj>xi

那么我们将点以x为第一关键字,y为第二关键字,排序后倒序插入线段树

线段树的线段这一维是离散后的y-x,值是y+x

我们要求的是大于yi-xi的最小的y+x,而xj>xi这个条件已经由插入顺序满足了

这样我们成功的解决了这个区域的点

而其他区域的点我们可以通过坐标变换转移到这个区域

由于对称性,我们注意到其实只要求x轴或y轴正半轴所在的四个区域就行了

那么这个问题就这样解决了

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <memory>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <climits>
#include <cstring>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <functional> //#define FIN freopen("input.txt","r",stdin);
//#define FOUT freopen("output.txt","w+",stdout);
using namespace std;
typedef long long ll; const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps=1e-8;
const double Pi=acos(-1.0);
const int N=50010; struct point
{
int x,y,id;
bool operator<(const point p)const
{
return x!=p.x?x<p.x:y<p.y;
}
} p[N];
struct BIT
{
int min_val,pos;
void init()
{
min_val=INF;
pos=-1;
}
} bit[N];
int par[N];//并查集中父亲
int hight[N];//并查集树的高度
struct edge
{
int u,v,cost;
};
edge G[N<<2];//边集(边数)
int V,E;//顶点数和边数
int get_Manhadm_dis(point a,point b)
{
return abs(a.x-b.x)+abs(a.y-b.y);
}
void addedge(int u,int v,int w)
{
G[E].u=u;
G[E].v=v;
G[E++].cost=w;
}
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int val,int pos)
{
for(int i=x; i>=1; i-=lowbit(i))
if(val<bit[i].min_val)
{
bit[i].min_val=val;
bit[i].pos=pos;
}
}
int ask(int x,int m)
{
int min_val=INF;
int pos=-1;
for(int i=x; i<=m; i+=lowbit(i))
if(bit[i].min_val<min_val)
{
min_val=bit[i].min_val;
pos=bit[i].pos;
}
return pos;
}
void make_edge()
{
int a[N],b[N];
for(int dir=0; dir<4; dir++)
{
if(dir==1||dir==3)
for(int i=0; i<V; i++)
swap(p[i].x,p[i].y);
else if(dir==2)
for(int i=0; i<V; i++)
p[i].x=-p[i].x;
sort(p,p+V);
for(int i=0; i<V; i++)
a[i]=b[i]=p[i].y-p[i].x;
sort(b,b+V);
int m=unique(b,b+V)-b;
for(int i=1; i<=m; i++)
bit[i].init();
for(int i=V-1;i>=0; i--)
{
int pos=lower_bound(b,b+m,a[i])-b+1;
int ans=ask(pos,m);
if(ans!=-1)
addedge(p[i].id,p[ans].id,get_Manhadm_dis(p[i],p[ans]));
update(pos,p[i].x+p[i].y,i);
}
}
}
//并查集初始化
void Init_union_find(int n)
{
for(int i=0; i<n; i++)
{
par[i]=i;
hight[i]=0;
}
}
//查询树的根
int find(int x)
{
if(par[x]==x)
return x;
else
return par[x]=find(par[x]);
}
//合并x和y所属的集合
void unite(int x,int y)
{
x=find(x);
y=find(y);
if(x==y)
return ;
if(hight[x]<hight[y])
par[x]=y;
else
{
par[y]=x;
if(hight[x]==hight[y])
hight[x]++;
}
}
//判断x和y是否属于同一个集合
bool same(int x,int y)
{
return find(x)==find(y);
}
bool cmp(const edge& a,const edge& b)
{
return a.cost<b.cost;
}
int kruskal()
{
sort(G,G+E,cmp);//按照edge.cost的顺序从小到大排列
Init_union_find(V);//并查集初始化
int ans=0;
for(int i=0; i<E; i++)
{
edge e=G[i];
if(!same(e.u,e.v))
{
unite(e.u,e.v);
ans+=e.cost;
}
}
return ans;
}
int main()
{
scanf("%d",&V);
for(int i=0; i<V; i++)
{
scanf("%d %d",&p[i].x,&p[i].y);
p[i].id=i+1;
}
E=0;
make_edge();
printf("%d\n",kruskal());
}

51nod 1213 二维曼哈顿距离最小生成树的更多相关文章

  1. [51nod1213]二维曼哈顿距离最小生成树

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

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

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

  3. 曼哈顿距离最小生成树 codechef Dragonstone

    曼哈顿距离最小生成树 codechef Dragonstone 首先,对于每一个点来说有用的边只有它向它通过 x=0,y=0,y=x,y=-x 切出来的八个平面的最近点. 证明 我不会 反正当结论记住 ...

  4. LA 3662 Another Minimum Spanning Tree (曼哈顿距离最小生成树 模板)

    题目大意: 曼哈顿最小距离生成树 算法讨论: 同上. 这回的模板真的准了. #include <iostream> #include <cstring> #include &l ...

  5. hdu6435 Problem J. CSGO标程讲解以及改正标程的一个错误(本来第一个样例过不了2333) 以及 poj2926 五维曼哈顿距离模板

    比赛的时候抄poj2926的模板,但改不来啊orz #include <iostream> #include <cstdio> #include <cstring> ...

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

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

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

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

  8. BZOJ 2735: 世博会 主席树+切比雪夫距离转曼哈顿距离

    2735: 世博会 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 124  Solved: 51[Submit][Status][Discuss] D ...

  9. Unity插件系列之二维码

    1.二维码常见的生成与识别途径 1.草料二维码 https://cli.im/text 2.在软件中实现生成和扫描二维码 使用zxing实现 zxing是一个用java写的开源项目,zxing.net ...

随机推荐

  1. Meteor ToDo App实例

    在本章中,我们将创建一个简单的待办事项应用程序. 第1步 - 创建应用程序 打开命令提示符,运行以下命令 - C:\Users\Administrator\Desktop>meteor crea ...

  2. [scrapy]实例:爬取jobbole页面

    工程概览: 创建工程 scrapy startproject ArticleSpider 创建spider cd /ArticleSpider/spiders/ 新建jobbole.py # -*- ...

  3. ExpandableListView的使用以及信息的高亮显示

    ExpandableListView是ListView控件的延伸,它能够对数据进行分组显示和隐藏,并统计总数量.可进行滚动,对某一内容高亮显示. <1>编写xml布局文件,用于获取Expa ...

  4. vue-cli中process.env配置以及打包本地运行或者线上运行配置

    我们知道打包默认npm run build,可是打包后点击dist文件中index.html一片空白.问题在于路径问题.我们在工程文件的最外层增加文件.env.production这个文件就是这么奇怪 ...

  5. 异或巧用:Single Number

    异或巧用:Single Number 今天刷leetcode,碰到了到题Single Number.认为解答非常巧妙,故记之... 题目: Given an array of integers, ev ...

  6. 书评第003篇:《0day安全:软件漏洞分析技术(第2版)》

    本书基本信息 丛书名:安全技术大系 作者:王清(主编),张东辉.周浩.王继刚.赵双(编著) 出版社:电子工业出版社 出版时间:2011-6-1 ISBN:9787121133961 版次:1 页数:7 ...

  7. JS表格分页组件:fupage的设计思路和详细使用方法(未来考虑开源,争取在2015年)

    一.背景         之前在秒针工作的时候,某js高级project师写了非常多自己的组件.当中一套是分页组件.叫做st-grid. 只是在我看来,bug太多.我常常给他反馈bug,我也不清楚为啥 ...

  8. input from 表单提交 使用 属性 disabled=&quot;disabled&quot; 后台接收不到name=&quot;username&quot;的值

    input from 表单提交 使用 属性 disabled="disabled" 后台接收不到name="username"的值

  9. Mac下Git项目使用的.gitignore文件

    https://www.gitignore.io/ 这个网站可以搜索特定项目.系统所需要的.gitignore 我现在主要是在Mac上用Visual Studio Code进行开发,所以直接搜索Mac ...

  10. java实用技能 上传文件 等等

    1.IOS  AES对称加密,加密结果不同,问题解决 IOS http post请求,使用AFNetworing 框架,默认请求content-type为application/json ,所以无法使 ...