【DFS】207. Course Schedule

#week19

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:

  1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
  2. You may assume that there are no duplicate edges in the input prerequisites.

分析:

这一题在之前有用拓扑排序做过

然后再DFS里面也看到了它

之前也分析过,实际上就是判断是否有环

所以DFS也可以进行判断是否有环

题解:

 1 class Solution {
 2 public:
 3     bool DFS(vector<unordered_set<int>> &matrix, unordered_set<int> &visited, int idx, vector<bool> &flag) {
 4         flag[idx] = true; // 标记该结点访问过
 5         visited.insert(idx);
 6         
 7         // 找出该结点的所有邻居结点,如果存在访问过的结点或者递归,则返回true
 8         for (auto it = matrix[idx].begin(); it != matrix[idx].end(); ++it) {
 9             if (visited.find(*it) != visited.end() || DFS(matrix, visited, *it, flag)) {
10                 return true;
11             }
12         }
13         
14         visited.erase(idx);
15         return false;
16     }
17     bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
18         vector<unordered_set<int>> matrix(numCourses);
19         // 要想完成第一门课程,则先完成第二门课程(后面的是先要完成的课程)
20         // 构建图
21         for (int i = 0; i < prerequisites.size(); ++i) {
22             matrix[prerequisites[i].second].insert(prerequisites[i].first);
23         }
24         
25         unordered_set<int> visited; // 记录一个递归访问过的结点
26         vector<bool> flag(numCourses, false); // 记录是否访问过结点
27         
28         /**
29          *  遍历所有课程,也就是结点
30          *  判断是否标记过结点,如果没有则进行DFS判断是否存在回路,存在回路则返回false
31          */
32         for (int i = 0; i < numCourses; ++i) {
33             if (!flag[i])
34                 // 如果递归中存在访问过的结点,则该拓扑排序是不存在的,也就无法完成课程
35                 if (DFS(matrix, visited, i, flag))
36                     return false;
37         }
38         return true;
39     }
40 }; 
原文地址:https://www.cnblogs.com/iamxiaoyubei/p/8278281.html