Jeremiah Willcock的answer是正确的,但细节。这是DAG的线性时间算法。
for each node v, initialize num_paths[v] = 0
let t be the destination and set num_paths[t] = 1
for each node v in reverse topological order (sinks before sources):
for each successor w of v:
set num_paths[v] = num_paths[v] + num_paths[w]
let s be the origin and return num_paths[s]
我敢肯定,一般有向图的问题是
#P-complete,但我无法找到除非cstheory的
unsourced question搜索的几分钟任何东西。
好的,这是一些伪代码。我已经将前面的算法的内容与拓扑排序相结合,并添加了一些循环检测逻辑。在s
和t
之间的循环的情况下,num_paths
的值可能不准确,但取决于t
是否可到达将为零非零。一个循环中的每个节点都不会有in_cycle
设置为true,但是每当一个SCC根(在Tarjan的SCC算法中)就足以触发提前退出,当且仅当s和t之间存在循环时。
REVISED ALGORITHM
let the origin be s
let the destination be t
for each node v, initialize
color[v] = WHITE
num_paths[v] = 0
in_cycle[v] = FALSE
num_paths[t] = 1
let P be an empty stack
push (ENTER, s) onto P
while P is not empty:
pop (op, v) from P
if op == ENTER:
if color[v] == WHITE:
color[v] = GRAY
push (LEAVE, v) onto P
for each successor w of v:
push (ENTER, w) onto P
else if color[v] == GRAY:
in_cycle[v] = TRUE
else: # op == LEAVE
color[v] = BLACK
for each successor w of v:
set num_paths[v] = num_paths[v] + num_paths[w]
if num_paths[v] > 0 and in_cycle[v]:
return infinity
return num_paths[s]
我认为你误读了CLRS,你会引用关于从书中找出O(n)中所有路径的确切段落吗? –
赛义德,恐怕我没有误读。这是第614,22.4.2页,CLRS 3版本上的练习题。 –