拓扑排序检测环

class Solution {
public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        vector<int> tp;                     // 存储拓扑排序结果
        vector<vector<int>> e(numCourses);  // 邻接表存储依赖关系
        vector<int> din(numCourses, 0);     // 每个节点的入度

        // 构建图
        for (auto &q : prerequisites) {
            int a = q[0], b = q[1];
            // b -> a
            e[b].push_back(a);
            din[a]++;
        }

        // 最小堆实现拓扑排序
        priority_queue<int, vector<int>, greater<int>> minHeap;

        // 将所有入度为 0 的节点加入最小堆
        for (int i = 0; i < numCourses; i++) {
            if (din[i] == 0) {
                minHeap.push(i);
            }
        }

        // 拓扑排序
        while (!minHeap.empty()) {
            int x = minHeap.top();  // 取堆中最小的节点
            minHeap.pop();
            tp.push_back(x);        // 将节点加入拓扑结果

            // 遍历当前节点的所有出边
            for (auto &p : e[x]) {
                if (--din[p] == 0) {  // 如果节点的入度变为 0
                    minHeap.push(p);  // 将节点加入最小堆
                }
            }
        }

        // 如果拓扑排序的结果数量不等于节点总数,则说明存在环
        if (tp.size() != numCourses) return {};

        return tp;
    }
};


class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        vector<vector<int>> g(numCourses);
        for (auto& p : prerequisites) {
            g[p[0]].push_back(p[1]);
        }

        vector<int> colors(numCourses);
        auto dfs = [&](this auto&& dfs, int x) -> bool {
            colors[x] = 1; // x 正在访问中
            for (int y : g[x]) {
                if (colors[y] == 1 || colors[y] == 0 && dfs(y)) {
                    return true; // 找到了环
                }
            }
            colors[x] = 2; // x 完全访问完毕
            return false; // 没有找到环
        };

        for (int i = 0; i < numCourses; i++) {
            if (colors[i] == 0 && dfs(i)) {
                return false; // 有环
            }
        }
        return true; // 没有环
    }
};

posted @ 2025-04-19 20:30  Qacter  阅读(16)  评论(0)    收藏  举报