1--课程表(207)

主要思路:
用 in 记录每一门课程剩余的先修课程个数,当剩余先修课程个数为0时,将该课程加入到队列q中。
每修队列q中的课程,以该课程作为先修课程的所有课程,其剩余先修课程个数减1;
不断将剩余先修课程数为0的课程加入到队列q中,当队列为空时,若修的课程数等于总课程数,则返回true,否则返回false;
#include <iostream>
#include <vector>
#include <queue>
class Solution {
public:
    bool canFinish(int numCourses, std::vector<std::vector<int>>& prerequisites) {
        std::vector<std::vector<int>> out; // 存储每一个先修课程对应的课程
        std::vector<int> in; // 存储每一个课程对应的剩余先修课程的个数
        std::queue<int> q; // 存储可以修的课程
        out.resize(numCourses);
        in.resize(numCourses);
        // 初始化
        for(auto pair : prerequisites){
            int cur = pair[0]; // 当前课程
            int pre = pair[1]; // 当前课程的先修课程
            out[pre].push_back(cur); // 初始化out
            in[cur]++;
        }
        // 选取可以直接修的课程加入到队列q中
        for(int i = 0; i < numCourses; i++){
            if(in[i] == 0) q.push(i);
        }
        int num = 0; // 已经修过的课程数
        while(!q.empty()){
            int tmp = q.front(); // 修弹出的课程
            q.pop();
            num++;
            // 以tmp作为先修课程的课程,其剩余的先修课程数减1
            for(auto course : out[tmp]){
                in[course] --;
                if(in[course] == 0) q.push(course); // course没有需要先修的课程了,因此可以加入到队列q中
            }
        }
        if(num == numCourses) return true;
        else return false;
    }
};
int main(int argc, char* argv[]){
    // numCourses = 2, prerequisites = [[1,0],[0,1]]
    std::vector<std::vector<int>> test = {{1, 0}, {0, 1}};
    int numCourses = 2;
    Solution S1;
    bool res = S1.canFinish(numCourses, test);
    if(res) std::cout << "true" << std::endl;
    else std::cout << "false" << std::endl;
    return 0;
}


















