关于曼哈顿距离下的最小生成树

曼哈顿距离最小生成树与莫队算法 一、曼哈顿距离最小生成树 曼哈顿距离最小生成树问题可以简述如下: 给定二维平面上的N个点,在两点之间连边的代价为其曼哈顿距离,求使所有点连通的最小代价。 朴素的算法可以用O(N2)的Prim,或者处理出所有边做Kruskal,但在这里总边数有O(N2)条,所以Kruskal的复杂度变成了O(N2logN)。 但是事实上,真正有用的边远没有O(N2)条。我们考虑每个点会和其他一些什么样的点连 阅读详情

这些天一直在集训,考了十几次……

zzy出了一道曼哈顿距离下的最小生成树,考场上我没做出来……

嗯……这种题目的问题在于,你没办法把每两个点都建一条边……

但是因为是曼哈顿距离,所以有一些特殊性质

容易证明,将某个点为原点建立笛卡尔坐标系,将坐标系分为每45°角为一块的八个区域

那么这个点向每个区域只会朝其中的某个点连边……

为什么说容易证明,因为我不会证……网上MS有这种证明的说……

贴一下zzy的题解:


所以我们只要求一个点在其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轴正半轴所在的四个区域就行了

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

不过,我没有找到地方提交这个题目……只是AC了zzy的题


代码在此:题目是求最小生成树上第k大边,使用了树状数组

//Lib
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>

#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
//Macro
#define	rep(i,a,b)	for(int i=a,tt=b;i<=tt;++i)
#define	drep(i,a,b)	for(int i=a,tt=b;i>=tt;--i)
#define	erep(i,e,x)	for(int i=x;i;i=e[i].next)
#define	irep(i,x)	for(typeof(x.begin()) i=x.begin();i!=x.end();i++)
#define	read()	(strtol(ipos,&ipos,10))
#define	sqr(x)	((x)*(x))
#define	pb	push_back
#define	PS	system("pause");
typedef	long long	ll;
typedef	pair<int,int>	pii;
const int oo=~0U>>1;
const double inf=1e100;
const double eps=1e-6;
string name="BRS", in=".in", out=".out";
//Var
int n,K,cnt,tot,ans;
int lisan[100008],l[100008];
int limit=1000000008;
struct P
{
	int x,y,idx;	
	bool operator <(const P &o)const{return x<o.x||x==o.x&&y<o.y;}
}d[100008];
struct BIT
{
	static const int limit=100000;
	int s[100008],p[100008];
	void set(){rep(i,1,limit)s[i]=oo;}
	inline int lowbit(int x){return x&-x;}
	void insert(int x,int v,int pos)
	{
		for(int i=x;i>0;i-=lowbit(i))
			if(s[i]>v)s[i]=v,p[i]=pos;
	}
	int query(int x)
	{
		int ret=oo,pos=n+1;
		for(int i=x;i<=n;i+=lowbit(i))
			if(s[i]<ret)ret=s[i],pos=p[i];
		return pos;
	}
}Q;
struct E
{
	int a,b,c;
	bool operator <(const E &o)const{return c<o.c;}
}e[1000000];
struct UNION
{
	int f[100008];
	static const int limit=100000;
	void set(){rep(i,1,n)f[i]=i;}
	int find(int x){return x==f[x]?f[x]:f[x]=find(f[x]);}
	void Union(int x,int y){f[x]=y;}
}U;
void Init()
{
	scanf("%d%d",&n,&K);
	rep(i,1,n)
		scanf("%d%d",&d[i].x,&d[i].y);	
}
void Discrate()
{
	rep(i,1,n)l[i]=d[i].y-d[i].x;
	sort(l+1,l+1+n);
	rep(i,1,n)lisan[i]=lower_bound(l+1,l+1+n,d[i].y-d[i].x)-l;
}
void add(int a,int b,int c){e[++tot].a = a;e[tot].b = b;e[tot].c = c;}
int Dis(int i,int j){return abs(d[i].x - d[j].x) + abs(d[i].y - d[j].y);}
void Solve()
{
	sort(d + 1,d + 1 + n);
	Discrate();Q.set();
	int pos;
	drep(i,n,1)
	{
		pos = Q.query(lisan[i]);
		if(pos != Q.limit + 1)
			add(d[i].idx,d[pos].idx,Dis(i,pos));
		Q.insert(lisan[i],d[i].y + d[i].x,i);
	}
}
void Kruskal()
{
	sort(e+1,e+1+tot);
	int x,y;int cnt=n-K;
	U.set();
	for(int i=1;i<=tot&&cnt;i++)
	{
		x=U.find(e[i].a);y=U.find(e[i].b);
		if(x!=y)
		{
			U.Union(x,y);
			cnt--;ans=e[i].c;
		}
	}
}
void Work()
{
	rep(i,1,n)d[i].idx=i;
	rep(i,1,4)
	{
		if(i == 3)
			rep(j,1,n)d[j].x = limit - d[j].x;
		if(i == 2 || i == 4)
			rep(j,1,n)swap(d[j].x,d[j].y);
		Solve();
	}	
	Kruskal();
	cout<<ans<<endl;
}
int main()
{
	freopen((name+in).c_str(),"r",stdin);
	freopen((name+out).c_str(),"w",stdout);
	Init();
	Work();
//	PS;
	return 0;
}
不知道是因为STL还是把数据结构封装在结构体里面的原因

这个程序效率巨低,开O2和不开O2差距达到1倍以上……虽然我觉得这种写法很优美就是了……

codeforces 100959B Airports 曼哈顿距离最大生成树 写了两种做法。 1. 对于每个点,向八个象限建最长边,注意最长边没有最短边的对称性,故每个点不能只枚举4个方向,要8个方向都枚举。这个做法速度较快,用的树状数组: #include using namespace std; typedef pair pii; const int maxn=100005; const int inf=2e9+1; int n,pos[maxn],f[maxn] 阅读详情

相关推荐

Ubuntu Server 22.04.5系统安装教程

该教程主要是演示在服务器上安装Ubuntu server 22.04系统的详细步骤,主要包含,安装系统前的准备(镜像的下载,启动盘的制作),安装系统时的语言选择,网络设置,切换镜像源(可根据实际需求来配置,本文使用清华镜像源),手动分区,用户设置,ssh服务安装等。以上就是关于Ubuntu Server 22.04系统安装的详细过程。

逆水行舟,不进则退。 7761

图论 —— 生成树 —— 曼哈顿距离最小生成树

【概述】 当给出一些二维平面的点时,记两点间距离为曼哈顿距离,此时的最小生成树,称为曼哈顿最小距离生成树。 对于 n 个点来说,最朴素的做法是暴力求出所有所有点两两之间的曼哈顿距离,然后再跑最小生成树算法,以得到曼哈顿最小距离生成树,但这样来做,由于总边数有 n^2 条,时间复杂度会达到 O(n^3) 或 O(n^2 logn) 对于 Kruskal 来说,针对这种曼哈顿距离的 MST 问题...

Alex_McAvoy的博客 4208

02-基于ART-PI开发板创建USB CDC 虚拟串口设备

本例在ART-PI开发板上,基于RT-Thread 5.0,5虚拟了一个USB32 CDC串口设备。

arm_fan的专栏 1886

曼哈顿距离最小生成树

一、前人种树 博客:曼哈顿距离最小生成树与莫队算法 博客:学习总结:最小曼哈顿距离生成树 二、知识梳理 曼哈顿距离:给定二维平面上的N个点,在两点之间连边的代价。(即distance(P1,P2) = |x1-x2|+|y1-y2|) 曼哈顿距离最小生成树问题求什么?求使所有点连通的最小代价。 最小生成树的“环切”性质:在图G = (V, E)中,如果存在一个环,那么把环上的最大...

weixin_34019144的博客 337

yersinia -G打不开图形化界面解决方案(曲线救国,实操可行)

附Kali 2021 VMware懒人版,已完成汉化,更新源,并已经安装yersinia。ping 114.114.114.114也不通,接着ifconfig发现 IP地址有的,然后手动配置了IP地址,发现还是Ping不通114.11.4.114.114,然后输入。更新源后,报错源无法解析,同时ping www.baidu.com也不通,那可能是DNS存在问题,更新一下DNS服务器。百度找了很久,有个回答比较接近,但一一尝试了几遍,还是无解,解决不了呀!•(2)Yersinia编译的时候,要选择gtk。

weilandeyongheng的专栏 4169

antv x6 沿边图标循环动画实现

2.使用transition给边设置动画,利用complte方法实现循环动画。实现效果,如下图,边上存在两个图标,要求图标延边一直循环动画。1.注册一个自定义边,边上定义两个图标,并设置其初始位置。

lingliu0824的博客 3366

知识点 - 曼哈顿距离最小生成树

知识点 - 曼哈顿距离最小生成树 解决问题类型: 求解曼哈顿距离上的最小生成树 前置知识 曼哈顿距离:给定二维平面上的N个点,在两点之间连边的代价。(即distance(P1,P2)=∣x1-x2∣+∣y1-y2∣distance(P1,P2) = |x1-x2|+|y1-y2|distance(P1,P2)=∣x1-x2∣+∣y1-y2∣) 曼哈顿距离最小生成树问题求什么?求使所有点连通...

qq_41848675的博客 993

避坑指南:DeepSeek Function calling流式输出中的常见问题与解决方案

本文深入探讨了在DeepSeek Function Calling中实现流式输出时常见的参数拼接、函数依赖管理和错误处理等核心挑战。针对流式响应中参数碎片化的问题,提供了健壮的参数拼接方案与状态管理策略。同时,文章详细阐述了如何管理函数调用顺序、处理条件性执行,并构建了分阶段的错误处理与重试机制,旨在帮助开发者构建稳定、高效的流式AI应用。

weixin_29062671的博客 203

曼哈顿距离最小生成树&莫队算法

参考资料:https://www.cnblogs.com/CsOH/p/5904430.html                   https://blog.youkuaiyun.com/huzecong/article/details/8576908                   https://www.cnblogs.com/xzxl/p/7237246.html              ...

二喵君的博客 1413

手把手教你接入京东购物小程序:从领券到下单的全流程解析

本文详细解析了如何从API申请到领券下单,手把手教你接入京东购物小程序的全流程。涵盖京东联盟账号注册、商品信息获取、优惠券链接转换等关键技术实践,帮助开发者高效实现电商功能集成,提升用户购物体验。

g5h6i的博客 910

Python爬虫实战:手把手教你用Selenium绕过药监局网站的反爬机制(附完整代码)

本文详细介绍了如何使用Selenium绕过药监局网站的反爬机制,提供了一套完整的Python爬虫实战方案。通过浏览器指纹伪装、动态等待策略、会话维持技巧以及分布式采集设计,帮助开发者高效爬取药监局数据,解决政府类网站常见的反爬挑战。

weixin_42620255的博客 737

POJ 3241 Object Clustering 二维平面曼哈顿距离最小生成树

题目链接:点击打开链接 题意: 给定二维平面上的n个点坐标,常数k 下面n行给出坐标 求一个最小生成树,问第k大的边是多少。 任意两个点间建一条边的花费是其曼哈顿距离。 思路:转自:点击打开链接 一、曼哈顿距离最小生成树 曼哈顿距离最小生成树问题可以简述如下: 给定二维平面上的N个点,在两点之间连边的代价为其曼哈顿距离,求使所有点连通的最小代价。 朴素的算法

九野的博客 2937

Grok-1.5+Ollama企业级本地化部署与合规实践指南

本文详细介绍了Grok-1.5+Ollama企业级本地化部署与合规实践指南,重点分析了本地化部署的成本优势和数据主权保障。通过RTX 4090显卡的硬件选型、Ubuntu 22.04系统优化及部署流程中的关键陷阱规避,为企业提供了高效、安全的AI模型部署方案。特别适合金融、医疗等敏感行业。

weixin_29094539的博客 182

二维平面曼哈顿距离最小生成树模版

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include const int inf = 1e8; const double eps =

九野的博客 2206

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

POJ3241 曼哈顿距离最小生成树

=.= 为什么莫队专题里面会有原理的题。。莫队是基于曼哈顿距离最小生成树提出的一种分块暴力(个人理解)算法,以后再说,先说这题。 因为不是图论选手,我图论非常菜,这题也是见都没见过,所以看了很多题解,来总结一下。 虽然说看了很多题解,但你搜搜就会发现,全部的讲解都是 一 模 一 样 的 !一点变动都没有的那种,所以我就直接写轮眼过来了。 http://poj.org/problem?id=3...

szudianchuang的博客 324

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

曼哈顿距离最小生成树与莫队算法(总结)

1 曼哈顿距离最小生成树 曼哈顿距离最小生成树问题可以简述如下: 给定二维平面上的N个点,在两点之间连边的代价为其曼哈顿距离,求使所有点连通的最小代价。 朴素的算法可以用O(N2)的Prim,或者处理出所有边做Kruskal,但在这里总边数有O(N2)条,所以Kruskal的复杂度变成了O(N2logN)。 但是事实上,真正有用的边远没有O(N2)条。我们考虑每个点会和其他一些什么样的点连边。可以得出这样一个结论,以一个点为原点建立直角坐标系,在每45度内只会向距离该点最近的一个点连边。 这个结论可以证明如

gyp0205的博客 1130

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

关于曼哈顿距离的最小生成树 POJ3241

题目地址 题目就是给你n个点 求n个点的曼哈顿距离的最小生成树 输出所有边中第k大的的边的权重。 n个点那么有有n∗(n−1)n*(n-1)条边如果采用朴素的prim算法建边就是O(n2)O(n^2)的复杂度,我们来考虑一下曼哈顿距离的特殊性,其实不是所有的边都需要,在建边的时候就可以去掉很多多余的边。 如图,对于给定的一些点我们选取一个点那么可以以这个点为原点建立一个直角坐标系,然后把每一个

touwangyi的博客 1199

为什么不可以使用哈曼顿距离_曼哈顿距离的最小生成树

最近测试有一道这样的题目,由于我以前看过怎么做,但是又不确定,所以就把做法的正确性证明了之后再做的。结果还是写挂了,只对了一个点。算法对于每个点,以它为中心把平面分成八个,每个面里面找一个距离它最近的点连一条边,然后做最小生成树即可。为什么这样是对的呢?如图,对于点\(O\)的其中一个平面,假设点\(A\)是离它最近的点,\(B\)点不是最近的点,我们可以证明,最小生成树里面可以不要\(OB\)这...

weixin_30402009的博客 186

曼哈顿距离的最小生成树

最近测试有一道这样的题目,由于我以前看过怎么做,但是又不确定,所以就把做法的正确性证明了之后再做的。结果还是写挂了,只对了一个点。 算法 对于每个点,以它为中心把平面分成八个,每个面里面找一个距离它最近的点连一条边,然后做最小生成树即可。 为什么这样是对的呢? 如图,对于点\(O\)的其中一个平面,假设点\(A\)是离它最近的点,\(B\)点不是最近的点,我们可以证明,最小生成树里面可以不要\(...

weixin_34400525的博客 131
上一篇: 关于Simpson积分
下一篇: [HNOI2011]卡农
OrpineX
博客等级 码龄17年 16粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值