图中的后边缘

时间:2017-06-12 08:10:48

标签: algorithm graph graph-theory depth-first-search tarjans-algorithm

我很难理解Tarjan的关节点算法。我目前在此处遵循此教程:https://www.hackerearth.com/practice/algorithms/graphs/articulation-points-and-bridges/tutorial/。我真正能够看到的,并且在任何其他教程中都看不到的,那就是"后边缘"手段。考虑到那里给出的图表,我知道3-1和4-2是后边缘,但也是2-1,3-2和4-3后边缘?谢谢。enter image description here

5 个答案:

答案 0 :(得分:5)

  

...后边缘是一个边缘,它将顶点连接到在它的父节点之前发现的顶点。

来自source

这样想:当您在图表上应用DFS时,您可以修复算法选择的路径。现在在给定的情况下:0->1->2->3->4。与上述文章一样,源图包含边4-23-1。当DFS达到3时,它可以选择1但是1已经在您的路径中,因此它是back edge,因此,如源中所述,可能是替代路径。

解决你的第二个问题:2-1,3-2和4-3也是后缘吗?对于不同的路径,他们可以。假设您的DFS选择0->1->3->2->4,然后2-14-3选择后边缘。

enter image description here

答案 1 :(得分:1)

从文章中提到:

  

给定图形的DFS树,后边缘是连接a的边缘   顶点到在它之前发现的顶点。

2-1,3-2,4-3不是"后缘"因为他们在DFS树中将顶点与父节点链接起来。

答案 2 :(得分:1)

本质上,当您执行DFS时,如果图中有节点A,B和C之间存在周期并且您已发现边AB,则稍后您会发现边BC,因为您已到达节点C,您将发现边缘CA,但您需要在搜索中忽略此路径以避免无限循环。因此,在您的搜索中,A-B和B-C不是后沿,但C-A是后沿,因为此边缘形成一个循环回到已访问过的节点。

答案 3 :(得分:1)

请考虑使用DFS进行以下(定向)图形遍历。在这里,节点的颜色表示以下内容:

  1. 花白色节点是尚待访问的
  2. 灰色节点是被访问并在堆栈上的节点
  3. 黑色节点是从堆栈中弹出的节点。

请注意,当节点13通过边缘13-> 0发现节点0时,节点0仍在堆栈中。这里,13-> 0是后边缘,表示存在一个循环(三角形0-> 1-> 13)。

enter image description here

答案 4 :(得分:0)

这是为了更好地理解代码:

#include<bits/stdc++.h>

using namespace std;

struct vertex{

    int node;

    int start;

    int finish;

    int color;

    int parent;

};


int WHITE=0, BLACK=1, GREY=2;

vector<int> adjList[8];

int num_of_verts = 8;
struct vertex vertices[8];

int t=0;

bool DFS_visit(int u){

    bool cycleExists = false;

    vertices[u].color=GREY;

    t++;

    vertices[u].start= t;


    for( int i=0;   adjList[u][i]!=-1; i++){

        if( vertices[adjList[u][i]].color == WHITE ){

            if(!cycleExists) cycleExists = DFS_visit(adjList[u][i]);

            else DFS_visit(adjList[u][i]);

        }

        else {

            cout << "Cycle detected at edge - ("<<u<<", "<<adjList[u][i]<<")"<<endl;

            cycleExists = true;
        }

    }

    vertices[u].color=BLACK;

    t++;

    vertices[u].finish= t;

    return cycleExists;

}

void DFS(){

    for(int i=0;i<num_of_verts;i++){

        vertices[i].color=WHITE;

        vertices[i].parent=NULL;

    }

    t=0;

    for(int i=0;i<num_of_verts;i++){

        if(vertices[i].color==WHITE){

           cout << "Traversing component "<<i<<"-"<<endl;


            bool cycle = DFS_visit(i);

            cycle==1? cout<<"Cycle Exists\n\n":cout <<"Cycle does not exist\n\n";

        
}
   
 }


}


int main(){


    adjList[0] = {4, -1};

    adjList[1] = {0, 5, -1};

    adjList[2] = {1, 5, -1};

    adjList[3] = {6, 7, -1};

    adjList[4] = {1, -1};

    adjList[5] = {-1};

    adjList[6] = {2, 5, -1};

    adjList[7] = {3, 6, -1};



    DFS();

    return 0;
}