Course Schedule

解题思路

  • 判断有向图中是否有环。
  • DFS 和 BFS 均可得到结果。

代码

// BFS
class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        auto graph = makeGraph(numCourses, prerequisites);
        auto degree = makeDegree(graph);
        queue<int> root;
        int count = 0;
        for (int i = 0; i < numCourses; ++i) {
            if (degree[i] == 0) {
                root.push(i);
            }
        }
        while (!root.empty()) {
            int node = root.front();
            count++;
            root.pop();
            for (int i : graph[node]) {
                if (--degree[i] == 0) {
                    root.push(i);
                }
            }
        }
        return count == numCourses;
    }
    
    vector<set<int>> makeGraph(int numCourses, const vector<pair<int, int>>& prerequisites) {
        vector<set<int>> graph(numCourses);
        for (auto c : prerequisites) {
            graph[c.second].insert(c.first);
        }
        return graph;
    }
    
    vector<int> makeDegree(const vector<set<int>>& graph) {
        vector<int> degree(graph.size(), 0);
        for (auto childs : graph) {
            for (int c : childs) {
                degree[c]++;
            }
        }
        return degree;
    }
};
// DFS
class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        auto graph = makeGraph(numCourses, prerequisites);
        vector<bool> pathed(numCourses, false);
        vector<bool> marked(numCourses, false);
        for (int i = 0; i < numCourses; ++i) {
            if (!marked[i] && hasCircle(graph, i, marked, pathed)) {
                return false;
            }
        }
        return true;
    }

    bool hasCircle(const vector<set<int>>& graph, int node, vector<bool>& marked, vector<bool>& pathed) {
        if (marked[node]) {
            return false;
        }
        marked[node] = pathed[node] = true;
        for (int child : graph[node]) {
            if (pathed[child] || hasCircle(graph, child, marked, pathed)) {
                return true;
            }
        }
        pathed[node] = false;
        return false;
    }
    
    vector<set<int>> makeGraph(int numCourses, const vector<pair<int, int>>& prerequisites) {
        vector<set<int>> graph(numCourses);
        for (auto c : prerequisites) {
            graph[c.second].insert(c.first);
        }
        return graph;
    }
};