老oj曼哈顿最小生成树
Description
平面坐标系xOy内,给定n个顶点V = (x , y)。对于顶点u、v,u与v之间的距离d定义为|xu – xv| + |yu – yv|
你的任务就是求出这n个顶点的最小生成树。
Input
第一行一个正整数n,表示定点个数。
接下来n行每行两个正整数x、y,描述一个顶点。
Output
只有一行,为最小生成树的边的距离和。
Sample Input
4
1 0
0 1
0 -1
-1 0
Sample Output
6 [数据约定]
对于30%的数据n <= 2000;
对于50%的数据n <= 5000;
对于100%的数据n <= 50000;
0 <= x, y <= 100000。 题解:http://blog.csdn.net/acm_cxlove/article/details/8890003
code:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#define maxn 50005
#define inf 1061109567
using namespace std;
char ch;
bool ok;
void read(int &x){
for (ok=,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
int n,m,ans=;
struct Point{
int x,y,d,id;
}point[maxn],tmp[maxn];
bool cmp1(Point a,Point b){
if (a.x!=b.x) return a.x>b.x;
return a.y>b.y;
}
int calc(Point a,Point b){return abs(a.x-b.x)+abs(a.y-b.y);}
struct Edge{
int u,v,c;
}edge[maxn<<];
bool cmp2(Edge a,Edge b){return a.c<b.c;}
int cntd,d[maxn];
struct DATA{
int val,pos;
void init(){val=inf,pos=-;}
void update(DATA b){if (val>b.val) val=b.val,pos=b.pos;}
};
struct bit{
#define lowbit(x) ((x)&(-(x)))
DATA node[maxn];
void init(){for (int i=;i<=cntd;i++) node[i].init();}
void insert(int x,DATA p){
x=cntd-x+;
for (int i=x;i<=cntd;i+=lowbit(i)) node[i].update(p);
}
int query(int x){
x=cntd-x+;
DATA ans; ans.init();
for (int i=x;i;i-=lowbit(i)) ans.update(node[i]);
return ans.pos;
}
}T;
void prepare(){
for (int i=;i<=n;i++) d[i]=point[i].y-point[i].x;
sort(d+,d+n+),cntd=unique(d+,d+n+)-d-;
for (int i=;i<=n;i++) point[i].d=lower_bound(d+,d+cntd+,point[i].y-point[i].x)-d;
sort(point+,point+n+,cmp1);
T.init();
for (int i=;i<=n;i++){
int u=point[i].id,v=T.query(point[i].d);
if (v!=-) edge[++m]=(Edge){u,v,calc(tmp[u],tmp[v])};
T.insert(point[i].d,(DATA){point[i].x+point[i].y,u});
}
}
int fa[maxn];
int find(int x){return x==fa[x]?fa[x]:fa[x]=find(fa[x]);}
int main(){
read(n);
for (int i=;i<=n;i++) read(point[i].x),read(point[i].y),point[i].id=i;
for (int i=;i<=n;i++) tmp[i]=point[i]; prepare();
for (int i=;i<=n;i++) point[i].x=tmp[i].y,point[i].y=tmp[i].x,point[i].id=i; prepare();
for (int i=;i<=n;i++) point[i].x=-tmp[i].y,point[i].y=tmp[i].x,point[i].id=i; prepare();
for (int i=;i<=n;i++) point[i].x=tmp[i].x,point[i].y=-tmp[i].y,point[i].id=i; prepare();
sort(edge+,edge+m+,cmp2);
for (int i=;i<=n;i++) fa[i]=i;
for (int i=,cnt=;i<=m&&cnt<n;i++)
if (find(edge[i].u)!=find(edge[i].v))
fa[find(edge[i].u)]=find(edge[i].v),cnt++,ans+=edge[i].c;
printf("%d\n",ans);
return ;
}
老oj曼哈顿最小生成树的更多相关文章
- 【BZOJ-2177】曼哈顿最小生成树 Kruskal + 树状数组
2177: 曼哈顿最小生成树 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 190 Solved: 77[Submit][Status][Discu ...
- BZOJ 2177: 曼哈顿最小生成树
Sol 考了好几次曼哈顿最小生成树,然而一直不会打...这次终于打出来了...神tm调试了2h...好蛋疼... 首先曼哈顿最小生成树有个结论就是讲它每45度分出一个象限,对于每个点,只与每个象限中离 ...
- POJ3241 Object Clustering 曼哈顿最小生成树
题意:转换一下就是求曼哈顿最小生成树的第n-k条边 参考:莫涛大神的论文<平面点曼哈顿最小生成树> /* Problem: 3241 User: 96655 Memory: 920K Ti ...
- poj 3241 Object Clustering (曼哈顿最小生成树)
Object Clustering Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 2640 Accepted: 806 ...
- POJ 3241 Object Clustering 曼哈顿最小生成树
Object Clustering Description We have N (N ≤ 10000) objects, and wish to classify them into severa ...
- BZOJ.2177.曼哈顿最小生成树(Kruskal)
\(Solution\) 参考 对于每个点,向唯一有可能与它形成MST的8个点连边,由于是双向单边,所以每个点最多连出4条边(证明见blog) 怎么找到一个区域内最近的点? 只考虑y轴右侧45°的区域 ...
- 常用OJ名字+地址(自用)
常用OJ名字+地址 不定期更新,自己用,有补充的也可以给我说说哈. 中文 openjudge 地址:openjudge.cn 说明:北大提供的一个平台,学校可申请小组: 比较好的小组: 计算概论:ic ...
- BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)
题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...
- 楼天城楼教主的acm心路历程(作为励志用)
楼主个人博客:小杰博客 利用假期空暇之时,将这几年GCJ,ACM,TopCoder 參加的一些重要比赛作个 回顾.昨天是GCJ2006 的回顾,今天时间上更早一些吧,我如今还清晰记得3 年 前,我刚刚 ...
随机推荐
- 初学scala2——case class
case class,样例类,有人也叫条件类. 例如: case class Person(name:String, age:Int) 好用之处: 1.新建类实例不用new Person(..),直接 ...
- google API的.NET库
Goolge发布了一个新的google API .NET库,是一个Portable Class Library,所以无论是.NET,WinTRy,Windows Phone或者Silverlight都 ...
- hdu 3720 Arranging Your Team 枚举
不可能解可以直接判断. 搭配产生的附加分可以用一个二维数组保存. 枚举1442,4种类型的人,因为总人数只有23个,所以可以搜索暴力枚举,然后保存最优解. 注意trick,答案可能为负数,所以初始化a ...
- TCP SOCKET中backlog参数的用途是什么? ---图解
recv_queue中的包大小,为内核的包大小,而不是ip包大小. 如果发出去的包太大,需要修改write_queue和tx_queue两个参数,tx_queue主要是流量控制. 多进程必须在sock ...
- XZ压缩
XZ压缩最新压缩率之王 xz这个压缩可能很多都很陌生,不过您可知道xz是绝大数linux默认就带的一个压缩工具. 之前xz使用一直很少,所以几乎没有什么提起. 我是在下载phpmyadmin的时候看到 ...
- Note | Javascript权威指南[第六版] 第1章:Javascript概述
JavaScript是一门高端的.动态的.弱类型的编程语言,非常适合面向对象和函数式的编程风格.JavaScript的语法源自Java,它的一等函数(first-class function)来 ...
- iOS-iPad开发之SplitViewController简单介绍
iOS-iPad开发之SplitViewController简单介绍 SplitViewController图形化创建 SplitViewController可以并列显示两个view,适用于基于nav ...
- NSNotificationCenter消息机制的介绍
转载自http://www.cnblogs.com/pengyingh/articles/2367374.html NSNotificationCenter的作用是专门提供程序中不同类之间的消息通讯而 ...
- Windows7如何在安全模式下卸载驱动(亲测)
在桌面“我的电脑”上点鼠标右键,选择“属性”,“硬件”,“设备管理器”,找到“显示卡选项”,打开前面的“+”,然后按鼠标右键,选择“卸载”就可以了. (亲测,主板驱动卸载成功启动)
- [转] 使用NVM快速搭建NODE开发环境
export NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node 本文主要介绍最近自己碰到的几个坑以及搜索到的相应解决方案: 如何快速搭 ...