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

严谨的论文请看:戳这里或者戳这里,还有一个blog的也可以看看:戳这里。

曼哈顿最小生成树&&莫队算法_第1张图片

可以证明每一个顶点在最小生成树中在这45度的范围内至多仅有一条边与之相连,也就是如果以一个点为原点,那么上面分成的八个区域里面最多和每个区域连一条边。

首先只考虑R1区间的。把每个坐标都按x为第一关键字,y为第二关键字排序。从后往前处理,那么能保证处理到第i个点时,比Xi大的点都已经处理过了。也就是以第i点为原点时,其他点只在R1,、R2、R3、R4区间。现在找R1区间的点,通过位移使得i点在原点,那么R1区间的点必然满足Xj<Yj,因为i点为原点,所以在原坐标中满足Xj-Xi<Yj-Yi,转移一下得Yj-Xj>Yi-Xi。也就是在Xj>Xi并且满足Yj-Xj>Yi-Xi中找一个离i点最近的点。因为Xi<Xj,Yi<Yj,所以曼哈顿距离为(Xj+Yj)-(Xi+Yi),后面的为常数,只考虑前面的即可。

总的算法是先排序,按x为第一关键字,y为第二关键字。然后以每个点的Yi-Xi的值得出排名F[i]。按排序的顺序倒序处理i点,每次找F[j]比F[i]大的并且是Xj+Yj最小的点连边。这个可以以F[i]作为标号,Xi+Yi作为值,用线段树或者树状数组维护即可。

考虑到对称性所以只需要处理4个区域,每个区域可以通过对称转移到R1,所以循环四次每次只是处理坐标,算法还是一样。

如果知道区间[l,r]的信息,可以O(1)得到[l+1,r]的信息,那么其转移复杂度就相当于曼哈顿距离。可以找出曼哈顿最小生成树然后按照连边处理信息。

最后是我的代码,只有处理边还没有求最小生成树的:

对于区间询问,还有一种根据查询分块的写法,例子见这里:小Z的袜子(hose) 分块

>_<没搞懂哪个才是莫队算法,还是都是。

← BZOJ 2038 [2009国家集训队]小Z的袜子(hose) 分块


原文来自:http://vawait.com/manhattanmst/

你可能感兴趣的:(编程,C++,c,算法,ACM)