Description


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

2 <= N <= 50000
坐标 0 <= x, y <= 1000000

输出N个点所组成的完全图的最小生成树的边权之和。

Solution


名字好长(#°Д°)
这似乎就是莫队复杂度的证明,但是莫队的做法不能得到最优解


图片来自这里

然后就可以用数据结构优化建图跑kruskal

对于建图的部分,我们只需要考虑由直线y=x和y轴的正半轴形成的区域内与当前点的关系。若点j是此区域内与点i最近的点则有
1. yj-xj>yi-xi
2. xj>xi
这是一个二维偏序问题,排序+树状数组搞搞就行
可以通过翻转xy、翻转x坐标、再翻转xy来把其他位置翻过来。注意到连边实际上是对称的,因此可以只做四次

之所以我们不选择直线y=x与x轴正半轴形成的区域,是因为这样做出来的直线需要考虑斜率为负数的情况,非常的麻烦。我一开始想当然地写了这个然后就wa了

Code


#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)
#define fill(x,t) memset(x,t,sizeof(x))
#define lowbit(x) ((x)&(-(x)))const int INF=0x3f3f3f3f;
const int N=100005;struct edge {int x,y,w;} e[N*4];
struct pos {int x,y,id;} p[N];int b[N],c[N],d[N],fa[N],n,size,edCnt;int read() {int x=0,v=1; char ch=getchar();for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());return x*v;
}void add_edge(int x,int y,int w) {e[++edCnt]=(edge) {x,y,w};// printf("%d %d %d\n", x,y,w);
}int get_dis(pos x,pos y) {return abs(x.x-y.x)+abs(x.y-y.y);
}int find(int x) {if (!fa[x]) return x;return fa[x]=find(fa[x]);
}bool cmpE(edge a,edge b) {return a.w<b.w;
}void MST() {int ans=0,cnt=0;std:: sort(e+1,e+edCnt+1,cmpE);rep(i,1,edCnt) {int fx=find(e[i].x),fy=find(e[i].y);if (fx!=fy) {fa[fx]=fy; cnt++;ans+=e[i].w;// printf("%d %d %d\n", e[i].x,e[i].y,e[i].w);}if (cnt==n-1) break;}printf("%d\n", ans);
}bool cmp(pos a,pos b) {return a.x<b.x||a.x==b.x&&a.y<b.y;
}int query(int x) {int ret=0,min=INF;for (;x<=size;x+=lowbit(x)) {if (c[x]<min) {min=c[x]; ret=d[x];}}return ret;
}void modify(int x,int v,int pos) {for (;x;x-=lowbit(x)) {if (v<c[x]) {c[x]=v; d[x]=pos;}}
}void build() {b[0]=0; rep(i,1,n) b[++b[0]]=p[i].y-p[i].x;std:: sort(p+1,p+n+1,cmp);std:: sort(b+1,b+b[0]+1);size=std:: unique(b+1,b+b[0]+1)-b-1;rep(i,0,size) {c[i]=INF; d[i]=0;};drp(i,n,1) {int pos=std:: lower_bound(b+1,b+size+1,p[i].y-p[i].x)-b;int ret=query(pos);if (ret) add_edge(p[ret].id,p[i].id,get_dis(p[i],p[ret]));modify(pos,p[i].x+p[i].y,i);}
}int main(void) {n=read();rep(i,1,n) p[i]=(pos) {read(),read(),i};build();rep(i,1,n) std:: swap(p[i].x,p[i].y);build();rep(i,1,n) p[i].x=-p[i].x;build();rep(i,1,n) std:: swap(p[i].x,p[i].y);build();MST();return 0;
}

51nod 1213 二维曼哈顿距离最小生成树 树状数组+最小生成树相关推荐

  1. 51nod 1213 二维曼哈顿距离最小生成树

    1213 二维曼哈顿距离最小生成树 基准时间限制:4 秒 空间限制:131072 KB 分值: 160 难度:6级算法题  收藏  关注 二维平面上有N个坐标为整数的点,点x1 y1同点x2 y2之间 ...

  2. HDU6681 二维偏序计算贡献值 树状数组 离散化

    http://acm.hdu.edu.cn/showproblem.php?pid=6681 交点个数加1就是答案 使用二维偏序计算横竖射线的交点 #include <bits/stdc++.h ...

  3. 【容斥原理】【推导】【树状数组】Gym - 101485G - Guessing Camels

    题意:给你三个1~n的排列a,b,c,问你在 (i,j)(1<=i<=n,1<=j<=n,i≠j),有多少个有序实数对(i,j)满足在三个排列中,i都在j的前面. 暴力求的话是 ...

  4. CDQ分治(二维CDQ 、三维CDQ+树状数组、四维CDQ+CDQ+树状数组)

    CDQ分治 CDQ分治相较于普通分治,多了左区间处理后对于右区间的影响. 利用这一点,CDQ分治可以用来做很多数据结构的题目(树状数组.线段树),加一个log的时间复杂度来优化一维. 操作: 假设有两 ...

  5. HDU-4456 Crowd 二维树状数组+坐标转换

    题意:给定一个N*N的网格,现在M组操作,一种操作时改变网格上的某个单点的权值,另外一种操作是求到一点曼哈顿距离为小于等于k的所有的权值和,初始化网格所有点的权值为0. 解法:这题如果没有那些特定的条 ...

  6. 数据结构一【树状数组】普通、二维、离线树状数组的(单点修改,单点查询,区间修改,区间查询)模板及应用例题总结

    文章目录 树状数组 lowbit 线段树与树状数组 单点修改 区间查询 区间修改 区间求和 二维树状数组 离线树状数组 例题 POJ:stars MooFest [SDOI2009]HH的项链 Tur ...

  7. HDU2642(二维的树状数组)

    二维的树状数组,我记得是模版!^ _ ^ 题意很清楚:就是这部分的原理:sum(x1,y1)+sum(x2-1,y2-1)-sum(x1,y2-1)-sum(x2-1,y1);其实可以和概率论中的一个 ...

  8. 点分治 + 树状数组 ---- E. Close Vertices(点分治 + 二维数点)

    题目链接 题目大意: 给出一棵树,问有多少条路径权值和不大于www,长度不大于lll 解题思路: 首先树上路径问题大概率就是点分治了 但是我们对于每个路径有两个性质就是(li,wi)(l_i,w_i) ...

  9. 二维树状数组 ----2021广东省赛 ----- K - Kera‘s line segment[区间转二维平面+树状数组维护前缀最小最大值]

    题目链接 题目大意: 就是一个一维的数轴上面有一堆线段用一个三元组(l,r,val)(l,r,val)(l,r,val)表示. 现在我们有两个操作: 就是往数轴上面添加线段 询问[L,R][L,R][ ...

最新文章

  1. 树上问题 ---- Codeforces Round #722 (Div. 1) C. Trees of Tranquillity [dfs序区间的性质+最大不相交区间的性质]
  2. 计算机科学领域最高荣誉,骄傲!这位毕业于嘉兴一中的数学家,荣获华人数学领域的最高荣誉...
  3. 报告解读丨企服 9 大规模化获客标杆模型(附赠案例)
  4. C/C++中 static 的作用
  5. apache+mod_wsgi+django的环境配置
  6. 计算机网络计技术段标 实训,计算机网络技术实训报告精选.pdf
  7. JDK、JRE、javac和JVM的关系
  8. 第十五讲 循环体for基础
  9. iOS对象的归档和解档-Runtime实现
  10. 在Linux环境下select函数的初体验
  11. java代码生成UUID以及在线UUID生成器
  12. 《软件工程导论》考研复习
  13. 电子罗盘的工作原理及校准
  14. 基于aspect的情感分析综述 论文翻译笔记 A Survey on Aspect-Based Sentiment Analysis: Tasks, Methods, and Challenges
  15. 是香蕉还是芭蕉,芭蕉和香蕉的区别
  16. 查看ASA日志服务器信息,ASA 日志管理
  17. win10变win7bios如何设置?
  18. 专家警告全球芯片短缺可能持续到 2022 年之后
  19. java算法:兔子生兔子
  20. 学习Python后,就业能从事哪些方向?

热门文章

  1. Excel操作:使用函数进行统计
  2. 网络安全笔记1——Internet协议的安全性
  3. ZOJ 3591 Nim (NIM博弈+统计
  4. css圆环进度条的几种方法
  5. 四步教你破解隔壁老王的Wi-Fi密码,蹭网没商量!
  6. r语言 断轴 画图_R语言作图——坐标轴截断画图
  7. 手机端扣扣浏览器图片居中_实现图片始终居中显示于浏览器窗口中心位置
  8. 《扬帆优配》个人养老金投资最新成绩出炉 七成养老FOF跑输基准
  9. 获取猫眼电影所有城市信息
  10. ARM hint instruction-WFI(Wait For Interrupt)指令详解