我必须开发一个与拓扑排序相关的O(| V | + | E |)算法,它在有向无环图(DAG)中确定从图的每个顶点到t的路径数(t是out-degree为0的节点。我已经开发了DFS的修改如下:
DFS(G,t):
for each vertex u ∈ V do
color(u) = WHITE
paths_to_t(u) = 0
for each vertex u ∈ V do
if color(u) == WHITE then
DFS-Visit(u,t)
DFS-Visit(u,t):
color(u) = GREY
for each v ∈ neighbors(u) do
if v == t then
paths_to_t(u) = paths_to_t(u) + 1
else then
if color(v) == WHITE then
DFS-Visit(v)
paths_to_t(u) = paths_to_t(u) + paths_to_t(v)
color(u) = BLACK
但我不确定这个算法是否与拓扑排序有关,或者我是否应该以另一种观点重构我的工作。
答案 0 :(得分:8)
可以使用动态编程和拓扑排序完成,如下所示:
Topological sort the vertices, let the ordered vertices be v1,v2,...,vn
create new array of size t, let it be arr
init: arr[t] = 1
for i from t-1 to 1 (descending, inclusive):
arr[i] = 0
for each edge (v_i,v_j) such that i < j <= t:
arr[i] += arr[j]
完成后,对于i
中的每个[1,t]
,arr[i]
表示从vi
到vt
现在,证明上述说法很简单(与您的算法相比,我不知道它是否正确以及如何证明它),它是通过归纳完成的:
基础: arr[t] == 1
,确实存在从t到t的单一路径,即空路径。
假设:对于k
范围内的每个m < k <= t
,声明均为真
证明:我们需要证明m
的声明是正确的。
让我们看看vm
:(v_m,v_i)
的每个边缘。
因此,从使用此边vt
的{{1}}开始的v_m
路径的数量。正是(v_m,v_i)
(归纳假设)。总结来自arr[i]
的外边缘的所有可能性,给出了从v_m
到v_m
的路径总数 - 这正是算法所做的。
因此,v_t
<强> QED 强>
时间复杂度:
第一步(拓扑排序)需要arr[m] = #paths from v_m to v_t
。
循环迭代所有边一次,所有顶点迭代一次,所以它也是O(V+E)
。
这使我们的总复杂度为O(V+E)