【发布时间】:2012-04-05 16:39:01
【问题描述】:
Algorithm Design Manual 很好地描述了 BFS 和 DFS。书中dfs的代码在决定是否避免双重处理边缘时存在问题。我找到了Errata 并将勘误表应用于代码,但我仍然认为精炼的代码存在检查双重处理边缘的问题。
我将优化后的代码粘贴如下:
dfs(graph *g, int v) {
edgenode *p;
int y;
if (finished) return;
discovered[v] = TRUE;
time = time + 1;
entry_time[v] = time;
process_vertex_early(v);
p = g->edges[v];
while (p != NULL) {
/* temporary pointer */
/* successor vertex */
/* allow for search termination */
y = p->y;
if (discovered[y] == FALSE) {
parent[y] = v;
process_edge(v,y);
dfs(g,y);
}
else if (**(!processed[y] && parent[v] != y)** || (g->directed))
process_edge(v,y);
if (finished) return;
p = p->next;
}
process_vertex_late(v);
time = time + 1;
exit_time[v] = time;
processed[v] = TRUE;
}
我认为有问题的地方用**标记。
所以有问题的地方是条件之一。假设它是无向图,那么我们可以忽略(g->directed)的条件。
好的,让我们首先关注parent[v] != y。如果parent[v] == y,当然我们不需要再次处理边v->y,因为在处理顶点y时,y->v已经处理过一次了。
如果parent[v] != y,我的问题是!processed[y] &&是否必要。
所以,如果 y 不是 v 的父级,并且processed[y] == false 表示 y 已经找到(否则执行无法到达 else if 部分)但没有被处理,所以 y 必须是 v 的祖母或以上. 这是一个后端,但没问题,我们可以处理它,因为它还没有被处理。
现在如果processed[y] == true 怎么办? 我认为这个“如果”永远不会发生,而且这个条件永远不会成立。
为什么?好的,让我们假设processed[y] 可以是真的。这意味着包含 y 的所有路径都已被处理,并且这些路径中的所有顶点也已被处理,对吧?因此,如果是这种情况,“尚未完成处理”的顶点 v 如何接近 y?
我认为在 dfs 中,没有顶点会接近已处理的顶点,对吗?
因此,如果我们永远不会处理已处理的顶点,我们可以删除 !processed[y],因为它总是正确的。
【问题讨论】:
-
如果我没记错的话,
processed[y]表示所有可能超出y的边都已被访问,对吧?在那种情况下,不,那不可能发生。也许它应该是&&ed 和g->directed?
标签: algorithm data-structures graph depth-first-search