解題說明
Minimum Number of Vertices to Reach All Nodes
題目描述:
給定一個有向無環圖(DAG),包含 n 個節點(編號 0 到 n-1)和一組有向邊 edges。找出最小的節點集合,使得從這個集合出發可以到達圖中所有節點。
解題思路: 關鍵觀察:如果一個節點沒有任何入邊(in-degree 為 0),那麼它不可能從其他任何節點到達,因此它必須被包含在答案集合中。反之,如果一個節點有入邊,它一定可以從某個其他節點到達,不需要被包含。
因此,答案就是所有入度為 0 的節點集合。只需遍歷所有邊,記錄哪些節點有入邊,最後收集所有沒有入邊的節點即可。
C++ 解法
複雜度分析
時間複雜度:O(n + E) — 遍歷所有邊標記入度,再遍歷所有節點收集結果,其中 E 為邊的數量。
空間複雜度:O(n) — 使用布林陣列記錄每個節點是否有入邊。
虛擬碼
1. Create boolean array hasIncoming of size n, initialized to false 2. For each edge (u, v) in edges: a. Set hasIncoming[v] = true 3. Create empty result list 4. For each node i from 0 to n-1: a. If hasIncoming[i] is false, add i to result 5. Return result
其他解法
使用 HashSet O(n + E):將所有邊的終點加入 HashSet,然後遍歷 0 到 n-1,不在 HashSet 中的節點即為答案。時間空間複雜度相同,但 HashSet 的常數因子比布林陣列大。
計算完整入度陣列 O(n + E):用整數陣列計算每個節點的精確入度值,再篩選入度為 0 的節點。功能上等價,但多記錄了不必要的資訊。
延伸思考
- 如果圖中有環(不是 DAG),此方法是否仍然正確?如何修改?
- 如果要求最小集合使得可以到達「至少 k 個節點」,該如何解決?
- 在無向圖中,等價的問題是什麼?如何求解?