深度優先遍歷之樹邊,前向邊,回邊,橫跨邊

2022-05-21 18:24:14 字數 1803 閱讀 1875

無意翻到一篇大佬的部落格,感覺寫得很好,給了我很大的幫助,特此**。

**:根據在有向圖g上進行深度優先遍歷所產生的深度優先森林,可以把圖中的邊分為四類:

(1)樹邊:是dfs森林的實際組成部分。如果頂點v是在探測邊(u,v)時首次被發現的,那麼(u,v)就是一條樹邊。

(2)前向邊::是dfs樹中從乙個頂點指向該頂點的乙個非子頂點後裔的邊。

(3)回邊:是dfs樹中從乙個頂點指向其祖先的邊(有向圖中可能出現的自環也被認為是反向邊)。

(4)橫跨邊:既不是從乙個頂點指向其後裔的邊,也不是指向其祖先的邊邊;橫跨邊是從乙個頂點指向乙個已完全訪問過的頂點的邊(即就是已經在該頂點上進行了postvisit操作的邊)。

對於每條邊(u, v),當第一次探測時,geneva所到達的頂點v的顏色和時間戳來判斷:

(1)(colour[v] == -1)表示它是一條樹邊。

(2)(colour[v] == 0)表示它是一條回邊。

(3)(colour[v] == 1)&&(d[u] < d[v])表示它是一條前向邊。

(4)(colour[v] == 1)&&(d[u] > d[v])表示它是一條橫跨邊。

如圖:實線表示樹邊,點線表示回邊,虛線表示前向邊,彎線表示橫跨邊。

具體實現**如下:

1 #include2 #include3 #include4

using

namespace

std;56

void dfs_visit(int

v);7

8int nodenum;//

圖中頂點數

9int edgenum;//

圖中邊數

10 vector< vector > mgraph;//

圖的儲存結構

11int *colour;//

初始化是-1,被探測是0,探測結束為1

12int *d;//

開始時間

13int *f;//

結束時間

14int t = 0;//

時間從零開始

1516

17//

深度優先搜尋

18void

dfs()

1924

25for(int i = 0; i < nodenum; ++i)

2631}32

}3334//

從節點v開始深度優先搜尋

35void dfs_visit(int

v)36

48else

if(colour[val] == 0)49

52else

5358

else

if(d[v] > d[val])//

後向邊5962}

63}64 f[v] = ++t;//

記錄結束時間

65 colour[v] = 1;66

}6768int

main()

6985

dfs();

86for (int i = 0; i < nodenum; i ++)

89 cout <

90for (int i = 0; i < nodenum; i ++)

93return0;

94 }

實現結果如下:

樹邊,前向邊,後向邊,橫叉邊

樹邊,前向邊,後向邊,橫叉邊,應該說,不是乙個圖本身有的概念,應該是圖進行dfs時才有的概念。圖進行dfs會得到一棵dfs樹 森林 在這個樹上才有了這些概念。對圖進行dfs,可以從任意的頂點開始,遍歷的方式也是多樣的,所以不同的遍歷會得到不同的dfs樹,進而產生不同的樹邊,前向邊,後向邊,橫叉邊。所...

鏈式前向星存邊

這邊文章是基於網上流傳最廣的改編,改了點內容方便更好的理解。我們輸入邊的順序為 1 2,2 3,3 4,1 3,4 1,1 5,4 5 void add int u,int v,int w 按上圖模擬一下 add 1,2,w1 edge 0 to 2 edge 0 next head 1 1 hea...

樹之深度優先遍歷

直接貼 只需要修改中間列印的位置,放在最前面就是先序遍歷,放在中間,就是中序遍歷,放在後面就是後序遍歷 貼 public class main public static void initnode node head public static void printf node node clas...