我们获得了一个带有N (up to 100,000)
个节点的树。每个边的权重为+1
或-1
,节点的编号从1
到N
。有多少无序对(A, B)
存在于路径A -> X -> B
上,其中X
(X != A && X != B
)是A
和{{1}之间路径上的某个顶点}},路径B
上的边权重之和为A -> X
,路径0
上的边权重之和为X -> B
?
因此我们只关心偶数路径长度,否则边缘权重之和不能是0
。我们无法迭代潜在的0
和A
,否则我们会得到一个B
解决方案,该解决方案不会在1秒内运行。有关如何解决的任何提示?该程序应该在1秒内运行,因此O(N^2)
或O(N)
解决方案可以正常运行。
编辑:但是,如果我们可以计算从每个节点开始的良好路径的数量,我们就能够解决问题。有可能计算出来吗?听起来对我而言,但我不确定。
答案 0 :(得分:0)
我将在下面开发一个以O(N^2)
开头的算法。通过小的观察我们可以将复杂性改变为更小的东西。我不太确定它会是什么(O(N)
或O(NlnN)
),但它似乎小于O(N^2)
。
x0
,并创建一个空列表L0
。L0
。重复,直到新节点上有3个或更多分支。L0, L1, L2, ...
的列表L0
。这些列表中的每一个代表不同的路径及其各自的累积总和。对于每个列表中的每一对,将m
这些总和等于零的次数添加到计数器。 这会将图表中每条可能路径的总和相关联。创建一个新列表L0
,它是集合L0, L1, L2, ...
。上述算法有效,但由于我们为每个图表路径执行求和,因此成本必须至少为O(N^2)
。
这里的诀窍是不计算每条路径。相反,如果我们对列表进行排序,则确定两个大小为k1,k2
的已排序列表是否具有固定总和c
可以通过简单地遍历列表来完成,一个向前向前迭代。因此,可以像以前那样在k1+k2
操作而不是k1*k2
操作中对每对列表进行计数。合并列表也很简单,并且具有相同的复杂性,因为它们已经排序。
奖励:上述方法可以简单地扩展任意边权重(不仅仅是-1, 1
)和任意固定总和(不仅仅是零)。
答案 1 :(得分:-1)
我不知道这是否有用,但如果有的话,我认为你可以使用这个属性:
选择存在此类路径的(A,B)
对。然后我们知道路径A -> ... -> B := d(A,B) = 0
的边权重(我将称之为末端顶点的距离)的总和,因为
d(A,B) = d(A,X) + d(X,B) = 0 + 0 = 0
正如你所说,我们只关心均匀长度的路径;这表明,当实际检查对时,我们首先用两种颜色对树进行着色(因为所有树都是二分的),这可以在Θ(n)中贪婪地完成,并且只考虑每个颜色组内的顶点对。当然,这并没有提高我们必须考虑的对的数量的复杂性,因为我们在每种颜色中仍然有(n / 2)*(n-1)/ 2个顶点,并且该项在Θ(n ^ 2)其中n
是顶点数。
现在正如您所说,您可以使用BFS计算Θ(n ^ 2)中的路径并检查每个颜色组中的所有顶点对。这是另一个可能对您有帮助的想法:
假设我们有两个顶点V和U d(A,V) = d(A,U)
。我们有两个案例:
A -> ... -> V = A -> ... -> U -> ... -> V
,意思是U(WLOG)位于从A到V的唯一路径上。然后我们有
d(A,V) = d(A,U) + d(U,V) <=> d(A,V) = d(A,V) + d(U,V) <=> d(U,V) = 0
因此,如果U和V位于同一条路径上且与A的距离相等,则距离为d(U,V) = 0
。
这两条路径在某处;让路径叉为K的顶点。然后我们有
d(A,V) = d(A,K) + d(K,V) <=> d(K,V) = d(A,V) - d(A,K)
和
d(A,U) = d(A,K) + d(K,U) <=> d(K,U) = d(A,U) - d(A,K)
和
d(U,V) = d(K,U) + d(K,V) = d(A,U) + d(A,V) - 2*d(A,K) = 2*(d(A,U) - d(A,K)) = 2 * d(K,U)
因此,如果U
和V
不在同一条路径上,它们之间的距离取决于顶点到A
的距离和距离{{1} }必须A
;或者,简化,只是在任一顶点到K
的距离。更一般地说,K
仅在任何顶点位于从d(A,U) = d(A,V)
到另一个顶点的路径上时,d(U,V) = 0
仅暗示A
的事实,因此您无法通过相等的距离真正说出任何内容如果后一种情况不是这样的话。
这是否会对你有所帮助,我不知道。我无法弄清楚如何在次级时间内实现你所要求的,我认为这是不可能的;对我来说,问题感觉与所有对最短路径有很大关系,其中每个顶点作为起始顶点使用BFS在O(n ^ 2)中具有时间复杂度。这更像是一种模糊的感觉,甚至比任何令人信服的论点都模糊不清。