课程问题

一. 课程表I

你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须先学习课程 bi 。
例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false

//判断是否存在拓扑排序
class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        vector<int> edges[numCourses];//重构图(邻接表)
        vector<int> indeg(numCourses);//记录顶点入度t
        for (const auto& info: prerequisites) {
            edges[info[1]].push_back(info[0]);//重构图(邻接表)
            ++indeg[info[0]];//构图时记录入度
        }

        stack<int> q;//栈和队列在这里没有区别,都是用来存储无前驱节点的容器
        for (int i = 0; i < numCourses; ++i) 
            if (indeg[i] == 0) q.push(i); //先存储所有初始化无前驱节点

        int visited = 0;//记录访问数,后面就不用判断入度表有没有清0
        while (!q.empty()) {//当队列不为空
            ++visited;//访问一次加一
            int u = q.top();q.pop();//无前驱节点出队列,该节点移除
            for (int v: edges[u]) {//遍历该节点后继
                --indeg[v];//出队列节点移除,其后继入度都减一
                if (indeg[v] == 0) q.push(v);//削减至无前驱则入队
            }
        }
        return visited == numCourses;//判断是否访问完所有节点
    }
};

二. 课程表II

求出任意一个拓扑排序

class Solution {
public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        vector<int> res;
        vector<int> edges[numCourses];//重构图(邻接表)
        vector<int> indeg(numCourses);//记录顶点入度t
        for (const auto& info: prerequisites) {
            edges[info[1]].push_back(info[0]);//重构图(邻接表)
            ++indeg[info[0]];//构图时记录入度
        }

        stack<int> q;//栈和队列在这里没有区别,都是用来存储无前驱节点的容器
        for (int i = 0; i < numCourses; ++i) 
            if (indeg[i] == 0) q.push(i); //先存储所有初始化无前驱节点

        int visited = 0;//记录访问数,后面就不用判断入度表有没有清0
        while (!q.empty()) {//当队列不为空
            int u = q.top();q.pop();//无前驱节点出队列,该节点移除
            res.push_back(u);
            for (int v: edges[u]) {//遍历该节点后继
                --indeg[v];//出队列节点移除,其后继入度都减一
                if (indeg[v] == 0) q.push(v);//削减至无前驱则入队
            }
        }
        if(res.size()==numCourses) return res;
        return {};
    }
};

三. 课程表III

课程有持续时间和截止时间,求最多能上几门课

四. 课程表IV

前课程置的前置也是前置课程

四. 并行课程II

一学期最多上k门课,求最少要多少学期

五. 并行课程III

可以同时上多门课,每门课有持续时间,
求最少月份

posted @ 2023-07-29 23:46  失控D大白兔  阅读(4)  评论(0编辑  收藏  举报