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.
Note:
The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
解法一:每个连通分量,只要出现回路,即说明冲突了。
回路检测如下:
存在a->b,又存在b->c,那么增加边a->c
如果新增边c->a,发现已有a->c,在矩阵中表现为对称位置为true,则存在回路。
注:数组比vector速度快。
class Solution { public: bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) { bool **preG; preG = new bool*[numCourses]; for(int i = 0; i < numCourses; i ++) preG[i] = new bool[numCourses]; for(int i = 0; i < numCourses; i ++) { for(int j = 0; j < numCourses; j ++) preG[i][j] = false; } for(int i = 0; i < prerequisites.size(); i ++) { int a = prerequisites[i].first; int b = prerequisites[i].second; if(preG[b][a] == true) return false; else { preG[a][b] = true; for(int j = 0; j < numCourses; j ++) { if(preG[j][a] == true) preG[j][b] = true; } } } return true; } };
解法二:不断删除出度为0的点,如果可以逐个删除完毕,说明可以完成拓扑序,否则说明存在回路。
class Solution { public: bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) { vector<int> outd(numCourses, 0); vector<bool> del(numCourses, false); unordered_map<int, vector<int> > graph; // construct reverse neighborhood graph // graph is to decrease the out-degree of a set of vertices, // when a certain vertice is deleted for(int i = 0; i < prerequisites.size(); i ++) { outd[prerequisites[i].first] ++; graph[prerequisites[i].second].push_back(prerequisites[i].first); } int count = 0; while(count < numCourses) { int i; for(i = 0; i < numCourses; i ++) { if(outd[i] == 0 && del[i] == false) break; } if(i < numCourses) { del[i] = true; // delete for(int j = 0; j < graph[i].size(); j ++) {// decrease the degree of vertices that links to vertice_i outd[graph[i][j]] --; } count ++; } else {// no vertice with 0-degree return false; } } return true; } };