直接回答:课程与先修关系构成有向图,「能否完成全部课程」等价于「图是否无环」,用拓扑排序判定。Kahn 算法(BFS):统计每个节点入度,入度为 0 的入队;反复取出队首、输出、并把它所有邻接点入度减 1、减到 0 再入队。若最终输出的节点数等于总数则无环,否则剩下的节点都在环上。

展开解析:DFS 版本用三色标记:白(未访问)→ 灰(访问中)→ 黑(已完成),遍历中遇到灰节点即发现回边、存在环——「灰节点冲突」是 DFS 判环的核心判据。复杂度都是 O(V + E)。工程里拓扑排序的应用值得主动提:构建系统(Makefile/Bazel 的依赖调度)、任务编排、包管理器安装顺序、Vue/前端模块的依赖解析。变体:课程表 II 要求输出一个合法修课顺序(Kahn 自然产出);「按字典序最小的拓扑序」把队列换成最小堆;判断拓扑序唯一性(每步队列长度是否恒为 1)。追问方向:为什么 Kahn 剩下来的节点必有环、并行场景下按层出队如何得到最短完成轮次。

示例

from collections import deque

def can_finish(num_courses, prerequisites):
    indeg = [0] * num_courses
    adj = [[] for _ in range(num_courses)]
    for course, pre in prerequisites:
        adj[pre].append(course)
        indeg[course] += 1
    queue = deque(i for i, d in enumerate(indeg) if d == 0)
    done = 0
    while queue:
        node = queue.popleft()
        done += 1
        for nxt in adj[node]:
            indeg[nxt] -= 1
            if indeg[nxt] == 0:
                queue.append(nxt)
    return done == num_courses