Tree 树边和前向边之间的差异

Tree 树边和前向边之间的差异,tree,graph-algorithm,depth-first-search,graph-traversal,Tree,Graph Algorithm,Depth First Search,Graph Traversal,我在读一本书的时候遇到了这个问题: 当DFS在图上运行时,如何从图中特定顶点的发现和完成时间来区分前向边和树边之间的差异 到目前为止,我尝试的是:Fwd和Fwd之间的主要区别。树边是,如果在a和B之间存在一个树边,那么a是B的直接邻居,路径长度为1,但如果是Fwd。边,则路径长度应大于1左右。因此,在分析可以存储在数组中的发现时间和完成时间时,我们可以检查它们的完成/开始时间是否相差1。因为如果他们这样做了,那就是树的边缘,否则就是向前的边缘 但是,我无法开发一种算法,也怀疑这种方法是否有缺陷。

我在读一本书的时候遇到了这个问题: 当DFS在图上运行时,如何从图中特定顶点的发现和完成时间来区分前向边和树边之间的差异

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


但是,我无法开发一种算法,也怀疑这种方法是否有缺陷。请帮帮我。谢谢。

如果在观察v时已定义了发现时间(v),并且在对有向图进行深度优先搜索时已定义了发现时间(u)且发现时间(u)则边(u,v)被分类为前向边,如果在观察v时已定义了发现时间(v),且发现时间(u)

  • 如果访问一个新的节点v(以前没有发现过v)从u
    than(u,v)是树的边

  • 否则,如果我们访问先前已访问的节点v

    • 如果我们还没有离开/完成该节点(v),那么v肯定是 u的祖先和(u,v)后缘

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

      • 它是一条前沿(从祖先到后代,u->v), 如果u的到达时间小于v

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

  • 供参考:

    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++;
    
    }
    
    void dfsredges(结构图*G,int v,int*visted,int*arrTime,int*depTime)
    {
    静态整数时间=0;
    访问量[v]=1;
    arrTime[v]=时间++;
    结构节点*temp=G->array[v];
    while(temp!=NULL)
    {
    如果(已访问[temp->val]!=1)
    {
    dfsEdges(G、temp->val、访问、到达时间、离开时间);
    }
    其他的
    {
    if(depTime[temp->val]=-1)
    printf(“\n%d-%d是后缘\n”,v,temp->val);
    其他的
    {
    if(arrTime[v]val])
    printf(“\n%d-%d为前沿”,v,temp->val);
    其他的
    printf(“\n%d-%d是交叉边\n”,v,temp->val);
    }
    }
    温度=温度->下一步;
    }
    depTime[v]=time++;
    }
    
    在有向图上执行深度优先搜索时

  • 如果访问一个新的节点v(以前没有发现过v)从u
    than(u,v)是树的边

  • 否则,如果我们访问先前已访问的节点v

    • 如果我们还没有离开/完成该节点(v),那么v肯定是 u的祖先和(u,v)后缘

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

      • 它是一条前沿(从祖先到后代,u->v), 如果u的到达时间小于v

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

  • 供参考:

    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++;
    
    }
    
    void dfsredges(结构图*G,int v,int*visted,int*arrTime,int*depTime)
    {
    静态整数时间=0;
    访问量[v]=1;
    arrTime[v]=时间++;
    结构节点*temp=G->array[v];
    while(temp!=NULL)
    {
    如果(已访问[temp->val]!=1)
    {
    dfsEdges(G、temp->val、访问、到达时间、离开时间);
    }
    其他的
    {
    if(depTime[temp->val]=-1)
    printf(“\n%d-%d是后缘\n”,v,temp->val);
    其他的
    {
    if(arrTime[v]val])
    printf(“\n%d-%d为前沿”,v,temp->val);
    其他的
    printf(“\n%d-%d是交叉边\n”,v,temp->val);
    }
    }
    温度=温度->下一步;
    }
    depTime[v]=time++;
    }