[英]How to count all reachable nodes in a directed graph?
有一个有向图(可能包含循环),每个节点上都有一个值,我们如何获得每个节点的可达值的总和。 例如,在下图中:
节点 1 的可达和为:2 + 3 + 4 + 5 + 6 + 7 = 27
节点 2 的可达和为:4 + 5 + 6 + 7 = 22
.....
我的解决方案:要获得所有节点的总和,我认为时间复杂度为 O(n + m),n 是节点数,m 代表边数。 应该使用DFS,对于每个节点,我们应该递归地使用一种方法来找到它的子节点,并在为它完成计算时保存子节点的总和,以便以后我们不需要再次计算它。 需要为每个节点创建一个集合,以避免循环导致无限计算。
它有效吗? 我觉得它不够优雅,尤其是要创建很多集合。 有没有更好的解决办法? 谢谢。
这可以通过首先找到强连通分量 (SCC)来完成,这可以在O(|V|+|E|)
。 然后,为 SCC 构建一个新图G'
(每个 SCC 是图中的一个节点),其中每个节点的值是该 SCC 中节点的总和。
正式地,
G' = (V',E')
Where V' = {U1, U2, ..., Uk | U_i is a SCC of the graph G}
E' = {(U_i,U_j) | there is node u_i in U_i and u_j in U_j such that (u_i,u_j) is in E }
那么,这个图(G')是一个有向无环图,问题变得更简单了,似乎是在评论中链接的问题的变体。
EDIT previous answer (strike out) 从这一点来看是一个错误,用新答案编辑。 对此感到抱歉。
现在,可以从每个节点使用 DFS 来查找值的总和:
DFS(v):
if v.visited:
return 0
if v is leaf:
return v.value
v.visited = true
return sum([DFS(u) for u in v.children])
此问题的 DP 解决方案 (DAG) 可以是:
D[i] = value(i) + sum {D[j] | (i,j) is an edge in G' }
这可以在线性时间内计算(在 DAG 的
拓扑排序之后)。
伪代码:
总时间为
O(|V|+|E|)
。
您可以使用DFS或BFS算法来解决您的问题。 两者都有复杂度O(V + E)
您不必计算所有节点的所有值。 而且你不需要递归。 做这样的事情。
通常 DFS 看起来像这样。
unmark all vertices
choose some starting vertex x
mark x
list L = x
while L nonempty
choose some vertex v from front of list
visit v
for each unmarked neighbor w
mark w
add it to end of list
在您的情况下,您必须添加一些行
unmark all vertices
choose some starting vertex x
mark x
list L = x
float sum = 0
while L nonempty
choose some vertex v from front of list
visit v
sum += v->value
for each unmarked neighbor w
mark w
add it to end of list
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.