到目前为止我所尝试的是:Fwd之间的主要区别。树边缘是如果在A和B之间存在树边缘,那么A是路径长度为1的B的直接邻居,但是如果是Fwd。边缘,那么路径长度应大于1左右。因此,在分析可以存储在数组中的发现和完成时间时,我们可以检查它们的完成/开始时间是否相差1.因为如果它们存在,则它是树边缘,否则是前沿。 / p>
但是,我无法开发算法,也怀疑这种方法是否有问题。拜托,帮帮我吧。谢谢。
答案 0 :(得分:3)
在有向图上进行深度优先搜索时,
如果您访问的是新节点v(之前未发现v) 比(u,v)是树边缘。
如果我们访问之前已访问过的节点v
如果我们尚未离开/完成该节点(v),那肯定是v 你的祖先和(你,v)后缘。
否则,有两种可能性 - 交叉边缘或前缘。在这两种情况下,我们都访问了一个已经离开的节点(v)。所以在这里, 我们可以使用到达时间来区分它们。
这是一个前沿(从祖先到后代,你 - > v), 如果你的到达时间会减少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++;
}
答案 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)行,如作者所建议的那样)。