Algorithm 二部图中的交叉数

Algorithm 二部图中的交叉数,algorithm,Algorithm,在二部图中,左侧有n个节点,右侧有m个节点。节点的顺序为1到n和1到m。左侧的节点连接到右侧的节点。未连接所有节点。例如: 1 is connected to 4 2 is connected to 3 3 is connected to 2 3 is connected to 1 我想知道图中有多少个交叉点(这里有5个交叉点)。类似的问题也在发生 我想知道如何使用一些用户提到的二叉索引树来解决这个问题。我用O(n^2)算法求解,得到TLE 这不是家庭作业。昨天我学到了一点,并在寻找一些

在二部图中,左侧有n个节点,右侧有m个节点。节点的顺序为1到n和1到m。左侧的节点连接到右侧的节点。未连接所有节点。例如:

1 is connected to 4

2 is connected to 3

3 is connected to 2

3 is connected to 1
我想知道图中有多少个交叉点(这里有5个交叉点)。类似的问题也在发生

我想知道如何使用一些用户提到的二叉索引树来解决这个问题。我用O(n^2)算法求解,得到TLE


这不是家庭作业。昨天我学到了一点,并在寻找一些问题,所以我遇到了这个。告诉我诀窍。请不要编写整个程序。

按左节点的索引对边排序,然后(对于相等的左索引)按右节点的索引排序。查看右节点的索引。图中的每个交叉点对应于一对索引,这些索引在该排序列表中不按顺序排列。你只需要数一数这样的“无序”对

按顺序将排序列表中右节点的每个索引插入到二叉索引树中。在每次插入之后,您可以在O(log(m))时间内找到树中已经有多少个较大的索引。因此,整个算法的时间复杂度为O(h*(log(h)+log(m)):O(h*log(h))用于排序,O(h*log(m))用于计算索引反转的数量(这里“h”是边的数量)。您可以使用基数排序或桶排序将其改进为O(h*log(m))


更新:

正如Android Decoded所注意到的,可以使用基于合并排序的分治算法来解决反演的数量问题。见详细说明。这种方法的时间复杂度O(h*log(h))比使用二叉索引树O(h*log(m))的复杂度大,但是对于稀疏图,边的数量不比节点的数量大很多,它应该更快,因为它需要更少的内存,并且对缓存更友好

如果在合并过程中消除重复条目,则合并排序方法的复杂性可能会提高到O(h*log(m))。为此,对(value,numberOfInstances)对应用合并排序,其中相邻的相同值组合成一个具有适当“numberOfInstances”的条目。在最坏的情况下,对于第一个日志(m)合并过程没有消除重复项,这具有O(h*log(m))的复杂性;然后,当在O(h)时间内快速消除重复项时,最多会保留日志(n)个过程

二叉索引树用法详细信息:

实现一个二叉索引树,对于给定的键可以返回其在树中的索引,从最大值开始(最大值->索引0,第二大值->索引1,…)。然后在将每个元素插入到树中之后,请求其索引,即排序列表中该元素左侧较大值的数目


更多细节:二叉索引树可以实现为一个搜索树,其每个节点都由后代节点的计数器进行扩充。不要为重复元素创建单独的节点,只需更新每个元素的子代节点计数器。当询问某个键的索引时,我们应该首先搜索一个节点,对应于树中的该索引;然后,我们应该对当前节点的每个祖先的直接右后代的所有计数器求和,包括当前节点本身的右后代,但不包括当前节点位于其某些祖先右侧的所有情况。

如果我正确理解了您的问题,那么

我们知道两个集合之间可以有NpowerM(让这个值为X)关系 如果我们能找到一个没有交集的集合(假设我们找到它是Y),那么我们从X中减去Y,这就是X-Y,从数学上回答你的问题。。
为了找到Y,你对另一边的元素进行排序,比如说在集合M上,然后找到最长的递增子序列(“http://en.wikipedia.org/wiki/Longest_increasing_subsequence这可以在O(nm)内完成,如果你足够聪明,那么你可以在O(NlogM)内完成。。。时间为明确解决方案(此处存在类似问题)http://people.csail.mit.edu/bdean/6.046/dp/“单击building bridges链接)

如果我正确理解了您的答案,它将以以下图形失败:{(1,3)、(2,4)、(3,1)、(4,2)}.Hmmm。。那看起来很酷。。令人惊叹的!排序后,此问题变为可通过合并排序解决的反转数问题。。令人惊叹的。。将在其他测试用例中验证它。。Thanks@AndroidDecoded:是的,合并排序在这里应该比索引树更有效。你能详细说明一下我们如何使用二叉索引树来解决这个问题吗?你应该重新考虑这个问题域。图形节点没有顺序,因此您可以绘制上面的示例图形,而不需要任何交叉(绘制两列3,1,2,4和1,2,4,3))。因此,您应该对节点的绘制方式施加一些几何约束,或者要求最小的交叉次数(然后您应该更正您的示例)。