树边缘与前缘之间的差异

时间:2015-03-31 14:39:01

标签: tree graph-algorithm depth-first-search graph-traversal

当我遇到这个问题时,我正在读一本书: 当运行DFS时,如何从图中特定顶点的发现和完成时间中区分出前缘和树边缘之间的区别?

到目前为止我所尝试的是:Fwd之间的主要区别。树边缘是如果在A和B之间存在树边缘,那么A是路径长度为1的B的直接邻居,但是如果是Fwd。边缘,那么路径长度应大于1左右。因此,在分析可以存储在数组中的发现和完成时间时,我们可以检查它们的完成/开始时间是否相差1.因为如果它们存在,则它是树边缘,否则是前沿。 / p>

但是,我无法开发算法,也怀疑这种方法是否有问题。拜托,帮帮我吧。谢谢。

2 个答案:

答案 0 :(得分:3)

在有向图上进行深度优先搜索时,

  1. 如果您访问的是节点v(之前未发现v) 比(u,v)是树边缘。

  2. 如果我们访问之前已访问过的节点v

    • 如果我们尚未离开/完成该节点(v),那肯定是v 你的祖先和(你,v)后缘。

    • 否则,有两种可能性 - 交叉边缘或前缘。在这两种情况下,我们都访问了一个已经离开的节点(v)。所以在这里, 我们可以使用到达时间来区分它们。

      • 这是一个前沿(从祖先到后代,你 - > v), 如果你的到达时间会减少v

      • 如果u的到达时间大于v,则为交叉边缘。

  3. 供参考:

    void dfsEdges(struct graph*G, int v, int *visited, int *arrTime, int *depTime)
    {
     static int time=0;
    
    
    visited[v]=1;
    arrTime[v]=time++;
    
    struct node *temp = G->array[v];
    while(temp!=NULL)
    {
        if(visited[temp->val] != 1)
        {
            dfsEdges(G,temp->val,visited,arrTime,depTime);
        }
        else
        {
            if(depTime[temp->val] ==-1)
            printf("\n%d - %d is back edge\n",v,temp->val);
            else
            {
                if(arrTime[v]<arrTime[temp->val])
                printf("\n%d - %d is forward edge\n",v,temp->val);
                else
                printf("\n%d - %d is cross edge\n",v,temp->val);
            }
    
        }
        temp=temp->next;
    
    }
    depTime[v]=time++;
    
    }
    

答案 1 :(得分:0)

如果在v观察时已经定义了discoveryTime(v)并且discoveryTime(u)&lt; = discoveryTime(v),则边缘(u,v)被分类为前沿。因此,边缘(u,u)也被分类为前沿。分类基于DFS遍历顶点的顺序,即从另一个顶点开始可能导致不同的分类。伪代码中的算法(带有解释和证明)可以在书中找到Kurt Mehlhorn: Data Structures and Efficient Algorithms, Volume 2, Springer Verlag, EATCS Monographs, 1984.(绝版但由作者在线提供),第4章,“图上的算法”,第21页,如下所示。我已经将第25页的片段包含在边缘分类中(第(8)到第(10)行,如作者所建议的那样)。

  

DFS algorithm with edge classification by [1]