法:广度优先遍历(拓扑排序)
- 每门课就是一个节点
- 学A之前必须学B,B->A是有向边
- 将入度为0的节点放入队列,拓扑排序最前面的点
- 每一步取出队首元素u,将u放入答案中
- 移除u的所有出边,将u的所有相邻节点v入度-1;若v的入度为0,将v放入队列
- 队列为空时,若答案中包含n个节点,则完成拓扑排序;否则,图中有环
- 该题中可用一个数字代替答案数组
class Solution {
private:
vector<vector<int>> edges;
vector<int> indeg;
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
//广度优先遍历
edges.resize(numCourses);
indeg.resize(numCourses);
for(auto info:prerequisites){
edges[info[1]].push_back(info[0]);
++indeg[info[0]];
}
queue<int> que;
for(int i=0;i<numCourses;i++){
if(!indeg[i]){
que.push(i);
}
}
int cnt=0;
while(!que.empty()){
int u=que.front();
que.pop();
++cnt;
for(auto v:edges[u]){
--indeg[v];
if(!indeg[v]){
que.push(v);
}
}
}
return cnt==numCourses?true:false;
}
};