207. 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.
题目就是有向图的环路问题,可以通过DFS递归来求解,维护一个visit向量,有3个值,0代表未访问,1代表已访问且已出栈,-1代表还未出栈,当一个结点遇到他指向结点的visit值为-1说明出现了环路。
也可以通过DFS算出节点的post值,对于每一条边起点的post值要大于终点的post值,说明无环路。
说明图(黑色是未访问,红色代表1,蓝色代表-1):
图五时2在栈顶,对于2->1的边,1对应的visit值为-1,即1在栈中,说明有环。
代码:
class Solution {
public:
void DFS(int temp, vector<vector<int> >& topo, vector<int>& visit, bool &res) {
visit[temp] = -1;
for (int i = 0; i < topo[temp].size(); i++) {
if (visit[topo[temp][i]] == -1) res = false;
if (visit[topo[temp][i]] == 0) DFS(topo[temp][i], topo, visit, res);
}
visit[temp] = 1;
}
bool canFinish(int numCourses, vector<pair<int, int> >& prerequisites) {
vector<int> visit(numCourses, 0);
vector<vector<int> > temp(numCourses);
int size = prerequisites.size();
for (int i = 0; i < size; i++) {
temp[prerequisites[i].first].push_back(prerequisites[i].second);
}
bool result = true;
for (int i = 0; i < numCourses; i++)
if (!visit[i]) DFS(i, temp, visit, result);
return result;
}
};