[英]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.