课程问题
一. 课程表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
可以同时上多门课,每门课有持续时间,
求最少月份