邊的分類(edge classification)
當深度優先搜尋執行時,它把圖切成一棵由發現邊構成的 DFS 樹,外加所有剩下的邊。美妙之處在於那些剩下的邊並非雜亂無章——每一條都依其兩端在樹中的位置落入少數幾種定義明確的類型,而知道一條邊的類型就告訴你關於圖結構的某件具體事情。「邊的分類」就是在每條邊被遇到時為它貼上標籤,是 DFS 幾乎免費產出的診斷讀數。
利用發現與完成時間戳,當 DFS 從 u 檢視一條邊 (u, v) 的當下,分類如下。若 v 未拜訪,它成為樹邊(用來發現 v 的那條邊)。若 v 已拜訪但仍「在堆疊上」——是 u 的祖先、其區間包含 u 的區間——它是回邊,由後代指向祖先。若 v 已完成且是 u 的後代(v 的區間巢狀於 u 之內,但 v 早先經由另一條路被抵達),它是前向邊。若 v 已完成且既非祖先也非後代(兩區間不相交),它是橫向邊,在兩條獨立分枝之間跳躍。你純粹從時間戳與一個「仍在堆疊上」的旗標就能判定身處哪種情況,所以分類不增加漸進成本:仍是 O(n + m)。
這些標籤是本領域其餘部分的原料。一條回邊恰是一個環的見證,因此「有沒有回邊?」就是環偵測。在有向無環圖中依定義沒有回邊,這正是拓樸排序得以可能的原因。前向邊與橫向邊只出現在有向 DFS(無向 DFS 只產生樹邊與回邊)。要記住的誠實提醒:這個分類是相對於某一次特定的 DFS 執行——不同的起點或鄰居順序可能把原本的橫向邊變成前向邊。不變且可信的是回邊的有無,因為那反映圖中真實的環,與你怎麼搜尋無關。
有向圖 a->b、b->c、a->c、c->a。從 a 跑 DFS 發現 a->b(樹邊)、b->c(樹邊),接著從 c 出發的邊 c->a 看到 a 仍在堆疊上:回邊(一個環 a-b-c-a)。稍後從 a 出發的邊 a->c 看到 c 已完成且巢狀於 a 內:前向邊。這裡沒有橫向邊出現。
時間戳加上一個在堆疊旗標就決定每條邊的類型;回邊是環確鑿無誤的標記。
無向 DFS 只會產生樹邊與回邊——前向邊與橫向邊是有向圖才有的現象。而這些標籤是相對於某一次 DFS 執行;唯有回邊的存在(真實的環)才與執行方式無關。