输入:
输出:
limit
,输出可以从第一个点到达的点数。A
可以达到B
iff AB <= limit
我目前的解决方案:
问题:
对于一大组限制,程序将运行缓慢(我需要为每个查询重新进行DFS)。我可以使用什么算法/数据结构来获得更好的性能?
答案 0 :(得分:1)
将所有对存储在数组中,按距离排序 而不是DFS,在数组的左(较小)部分执行union-find algorithm。您将获得不相交(有时是联合)森林,其中包含第一个点的组件的等级是您想要的。
请注意,随着距离的增加,等级会单调增加。
现在从左到右遍历所有数组,并记下到Dist数组的距离,并达到Rank数组的第一个组件的等级。
现在为每个限制查询在Dist数组中找到此值位置索引(使用二进制搜索)并从Rank数组中获取相应的值 - 每个查询的复杂度为
为O(log(N ^ 2))= <强> O(的log(n))强>
答案 1 :(得分:0)
当考虑欧几里德距离时,具有整数坐标没有多大帮助:点(0,0)和(1,1)相隔sqrt(2),这不是整数,甚至不是理性的。幸运的是,您不必在距离上做任何算术,只需比较它们,这样您就可以存储和比较距离的整数平方。
我能看到的最佳方式(但我不是这类问题的专家!)是建立一个最小生成树(参见this comment),然后将其分成几部分:对于每个给定的限制删除超过该限制的分支,然后识别剩余的连接组件(Wikipedia) - 这些是您的“可达子集”。
如果从最大限制开始并进入最小限制,则可以迭代地执行任务:每个分支删除都会将分支所属的组件拆分为两部分,但不会影响其他组件。这可以简化工作,前提是数据结构允许有效地关联分支和子图。
答案 2 :(得分:0)
如果您使用Dijkstra算法进行最短路径查找的变体,请参阅https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm,您可以使用O(n*log(n))
。这将标记所有点与一个起始点的距离。然后你只需排序(O(n*log(n))
)并输出它们(O(n*l)
以获得天真的方法;如果你有很多限制,那么先排序它们,最后得到O(n*log(n) + l*log(l))
)。