無意翻到一篇大佬的部落格,感覺寫得很好,給了我很大的幫助,特此**。
**:根據在有向圖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...