🗺️ Graphs

走訪、連通分量與拓樸排序。

39 題

📖 分類導讀

圖由頂點 (Vertex) 和邊 (Edge) 組成,用來表示物件之間的關係。BFS 和 DFS 是最基本的圖遍歷演算法。

Notes:

  • 圖的表示方式:鄰接矩陣 vs 鄰接表
  • BFS 適合最短路徑(無權圖),DFS 適合連通性和路徑探索
  • Union-Find 適合處理動態連通性問題
  • 拓撲排序用於有向無環圖 (DAG) 的依賴關係

兩種表示法

表示法空間查「u→v 是否相鄰」適合
鄰接矩陣O(V^2)O(1)稠密圖、頻繁查邊
鄰接表O(V + E)O(deg)稀疏圖(多數題目)

NOTE

鄰接表本質上就是「稀疏矩陣的壓縮」:真實世界的圖大多稀疏(邊遠少於 V^2),只存實際存在的邊能省下大量空間,這也是大規模圖(社群網路、網頁連結)唯一可行的存法。

DFS 與 BFS 模板

兩者時間都是 O(V + E)、空間 O(V),差別在用 stack(遞迴)還是 queue,以及探索順序。

// DFS:遞迴,適合連通分量、路徑探索、偵測環
fun dfs(u: Int, graph: List<List<Int>>, visited: BooleanArray) {
    visited[u] = true
    for (v in graph[u]) {
        if (!visited[v]) dfs(v, graph, visited)
    }
}

// BFS:佇列,適合無權圖最短路、逐層擴散
fun bfs(start: Int, graph: List<List<Int>>): IntArray {
    val dist = IntArray(graph.size) { -1 }
    val queue = ArrayDeque<Int>()
    dist[start] = 0
    queue.add(start)
    while (queue.isNotEmpty()) {
        val u = queue.removeFirst()
        for (v in graph[u]) {
            if (dist[v] == -1) {          // 未訪問
                dist[v] = dist[u] + 1
                queue.add(v)
            }
        }
    }
    return dist
}

IMPORTANT

圖題務必維護 visited,否則有環時會無限繞圈。網格題(島嶼類)可把每個格子視為節點、上下左右為邊,套同一套 BFS/DFS。

圖的屬性

動手前先確認:有向 / 無向、加權 / 無權、是否可能有環、是否連通。這些屬性決定該用哪種演算法——例如無權最短路用 BFS,加權非負用 Dijkstra,有負權用 Bellman-Ford(見 Advanced Graphs)。

跨倉庫導讀

  • 對應理論章節:
#126Word Ladder IIHard★★★★★⏱ O(N·L·26)#127Word LadderHard★★★★⏱ O(m^2 * n)#130Surrounded RegionsMedium★★★★⏱ O(m * n)#133Clone GraphMedium★★★★★⏱ O(V + E)#200Number of IslandsMedium★★★★★⏱ O(m * n)#207Course ScheduleMedium★★★★★⏱ O(V + E)#210Course Schedule IIMedium★★★★⏱ O(V + E)#261Graph Valid TreeMedium★★★★★⏱ O(E * α(n))#286Walls and GatesMedium★★★★★⏱ O(m * n)#323Number of Connected Components in an Undirected GraphMedium★★★★★⏱ O(E * α(n))#399Evaluate DivisionMedium★★★★★⏱ O(Q * (V + E))#417Pacific Atlantic Water FlowMedium★★★★★⏱ O(m * n)#463Island PerimeterEasy★★★★★⏱ O(m * n)#684Redundant ConnectionMedium★★★★⏱ O(n * α(n))#695Max Area of IslandMedium★★★★⏱ O(m * n)#721Accounts MergeMedium★★★★⏱ O(N * K * α(N * K))#752Open The LockMedium★★★★★⏱ O(10^4 * 4)#785Is Graph Bipartite?Medium★★★★★⏱ O(V + E)#802Find Eventual Safe StatesMedium★★★★★⏱ O(V + E)#909Snakes And LaddersMedium★★★★★⏱ O(n^2)#934Shortest BridgeMedium★★★★★⏱ O(n^2)#953Verifying An Alien DictionaryEasy★★★★★⏱ O(n * m)#994Rotting OrangesMedium★★★★⏱ O(m * n)#1020Number of EnclavesMedium★★★★★⏱ O(m * n)#1091Shortest Path in Binary MatrixMedium★★★★★⏱ O(n^2)#1129Shortest Path with Alternating ColorsMedium★★★★★⏱ O(V + E)#1162As Far from Land as PossibleMedium★★★★★⏱ O(n^2)#1254Number of Closed IslandsMedium★★★★★⏱ O(m * n)#1462Course Schedule IVMedium★★★★★⏱ O(V^2 + E + Q)#1466Reorder Routes to Make All Paths Lead to The City ZeroMedium★★★★★⏱ O(n)#1553Minimum Number of Days to Eat N OrangesHard★★★★★⏱ O(log^2(n))#1557Minimum Number of Vertices to Reach all NodesMedium★★★★★⏱ O(V + E)#1857Largest Color Value in a Directed GraphHard★★★★★⏱ O((V + E) * 26)#1905Count Sub IslandsMedium★★★★★⏱ O(m * n)#1958Check if Move Is LegalMedium★★★★★⏱ O(8 * 8)#2101Detonate the Maximum BombsMedium★★★★★⏱ O(n^3)#2359Find Closest Node to Given Two NodesMedium★★★★★⏱ O(n)#2477Minimum Fuel Cost to Report to the CapitalMedium★★★★★⏱ O(n)#2492Minimum Score of a Path Between Two CitiesMedium★★★★★⏱ O(V + E)