Course Schedule

There are a total of n courses you have to take, labeled from 0 to n - 1.

Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

For example:

2, [[1,0]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.

2, [[1,0],[0,1]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.



图论中的一个典型题目,求有向图的拓扑排序,这里相对简化了一些,只需要判断一个图是否是DAG

思路:

所有的拓扑排序都从一个入度为0的点开始(本例中就是一个不需要任何铺垫课程的课程),从图中移除该点和从它发出的所有边。重复这一过程直到所有的点都移除(表明该图是一个DAG)或者剩余的点里没有入度为0的点了(不是DAG)。

代码:

class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int> >& prerequisites) {
if(numCourses == 0 || prerequisites.empty()) return true;
int nedge = prerequisites.size();

vector<int> indeg(numCourses, 0);
vector<vector<int> > edges(numCourses, vector<int>());
vector<bool> visited(numCourses, false);
int count = 0;

for(int i = 0; i < nedge; ++i){
++indeg[prerequisites[i].first];
edges[prerequisites[i].second].push_back(prerequisites[i].first);
}

while(count < numCourses){
int i = 0;
for(; i < numCourses; ++i) if(!visited[i] && indeg[i] == 0) break;
if(i == numCourses) return false;
visited[i] = true;
int nout = edges[i].size();
for(int j = 0; j < nout; ++j) --indeg[edges[i][j]];
++count;
}
return true;
}
};