如何计算有向图中的所有可到达节点?

时间:2018-01-22 19:45:56

标签: algorithm graph directed-graph

有一个有向图(可能包含循环),每个节点上都有一个值,我们怎么能得到每个节点的可达值之和。例如,在下图中:

directed graph

节点1的可达和为:2 + 3 + 4 + 5 + 6 + 7 = 27

节点2的可达和为:4 + 5 + 6 + 7 = 22

.....

我的解决方案:为了获得所有节点的总和,我认为时间复杂度为O(n + m),n是节点数,m代表边数。应该使用DFS,对于每个节点,我们应该递归地使用一个方法来找到它的子节点,并在完成计算时保存子节点的总和,这样以后我们就不需要再次计算它了。需要为每个节点创建一个集合,以避免由循环引起的无限计算。

有用吗?我不认为它足够优雅,特别是必须创建许多套装。有没有更好的解决方案?感谢。

2 个答案:

答案 0 :(得分:5)

这可以通过首先找到Strongly Connected Components (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')是DAG,问题变得更简单,似乎是question linked in comments的变体。

针对此问题的DP解决方案(DAG)可以是:

D[i] = value(i) + sum {D[j] | (i,j) is an edge in G' }

这可以在线性时间内计算(在DAG的topological sort之后)。

伪代码:

  1. 查找SCC
  2. Build G'
  3. 拓扑排序G'
  4. 为G'
  5. 中的每个节点找到D [i]
  6. 为U_i中的所有节点u_i应用值,对于每个U_i。
  7. 总时间为O(|V|+|E|)

答案 1 :(得分:2)

您可以使用DFSBFS算法来解决您的问题。 两者都有复杂性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