原题地址
https://leetcode.com/problems/course-schedule/
题目描述
There are a total of n courses you have to take, labeled from 0 to n - 1.
你需要上n个课程,标记为0~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]
有些课程有前导课,比如你要上课程0必须先上课程1,我们用一个整数对[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个课程,你需要先上课程0再上课程1,因此是可能的。
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.
共有2个课程,你需要先上课程0再上课程1,而且上课程1之前你必须先上课程0,因此这是不可能的。
Note:
注意:
The input prerequisites is a graph represented by a list of edges, not adjacency matrices.
输入的先序关系代表着一个图的边,不是邻接矩阵。
Hints:
提示:
- This problem is equivalent to finding if a cycle exists in a directed graph. If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses.
这个问题等价于判定一个有向图中是否存在环。如果存在环,就不存在拓扑序,也就是不可能上完所有的课程。- Topological Sort via DFS.
拓扑排序可以用深度优先搜索来实现。- Topological sort could also be done via BFS.
拓扑排序可以用广度优先搜索来实现。
Tags Depth-first Search
Breadth-first Search
Graph
Topological Sort
解题思路
使用广度优先搜索来实现拓扑排序的解题思路类似于这个题 hihocoder 47 拓扑排序 · 一,所以此处就不做描述了。代码和测试数据后面给出。
使用深度优先搜索的解题思路跟广度优先搜索类似,差别在于我们不是根据入度来确定搜索次序,而是根据出度来确定搜索次序,即维护出度为0的结点的集合,依次移除这些结点,并更新未其相应边的出度,直至所有结点的出度不再变化
,如果最终所有结点的出度都为0则不存在环。
在判断有向图是否有环的问题上,bfs和dfs的区别仅在是按照入度还是出度来考虑问题上。
另外,关于课程的具体顺序,详见Leetcode 210 Course Schedule II
代码
dfs
class Solution {
public:
/**
* 能否完成所有的课程
* dfs拓扑排序,看有向图是否存在环
* @param numCourses 课程数量
* @param prerequisites 课程先序关系
* @return 能完成返回true,否则false
*/
bool canFinish(int numCourses, vector<pair<int, int> >& prerequisites) {
vector<int> heads(numCourses, -1), degree(numCourses, 0), points, args;
pair<int, int> p;
int from, to, count = 0, len = prerequisites.size();
/* 构造有向图,邻