我有一个有N个顶点的树。我想设计一种算法来快速回答一些查询。给定顶点V和整数d,我想在距离为d的距离为d的顶点找到顶点。如果在距离d处有多个顶点,则输出任意顶点。我显然知道如何做蛮力。我也试过一些类似于LCA发现算法的想法(计算距离为1,2,4,8 ......的祖先),但没有任何结果。
我会有很多查询,比如10 ^ 6,所以我想在O(1)或O(log N)时间内回答它们
答案 0 :(得分:1)
这种方法可行
这是有效的,因为如果对于具有深度(v)> = d的查询(v,d)存在答案,则由于x的属性,存在从v开始的跨越x的长度d的路径。
您可以使用单个深度优先搜索来实施步骤1和步骤。
对于步骤4,您希望保留一个哈希表,该哈希表以您可以删除的方式将深度与顶点相关联,并在O(1)中添加顶点。然后,您可以在按组件工作时以线性时间执行它。
总运行时间为O((n + q)* log n)。
这可以通过使用持久二进制搜索树预先计算步骤4中的深度数据结构在线进行,再次在每个查询的O(log n)中。
答案 1 :(得分:0)
为树的每个边添加一个权重,对应于后代的数量。这只能进行一次,并且是O( N )
如果您只想在特定距离 d 找到一个顶点,您可以在O( d )步骤中执行此操作,只需将树向上走,最后向下,如一旦你找到一个足够重的分支来进行 d 步骤。
如果您在同一棵树上进行了很多查询,这将表现得非常好。
答案 2 :(得分:0)
为给定节点构建图形/添加链接 您可以存储该顶点的边缘地图,其中距离为关键点,边距为该值。这样您就可以在O(1)
中构建和检索class Vertex{
String vertexLabel;
Map<Integer,List<Edge> edgeMap;
}
答案 3 :(得分:-1)
一旦你的图形运行Floyd-Warshall算法,计算所有对之间的最短路径,然后使用它? 也许只是从V开始的深度优先搜索并且在深度d处停止就足够了,这取决于您打算执行多少查询。