拓扑排序的原理及其实现
LeetCode 207. Course Schedule
LeetCode discuss
Kahn算法
- 从有向图中选取一个没有前驱(即入度为0)的顶点,并输出之;
- 从有向图中删去此顶点以及所有以它为尾的弧;
- 如果最后还有顶点,则图中有环
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<vector<int>> matrix(numCourses); //邻接表
vector<int> indegree(numCourses); //点的入度
for (auto it : prerequisites) {
matrix[it.second].push_back(it.first);
indegree[it.first]++;
}
queue<int> q;
for (int i = 0; i < numCourses; ++i) {
if (indegree[i] == 0) q.push(i); //入度为0的顶点加入
}
int removed_nodes = 0;
while (!q.empty()) {
int course = q.front();
q.pop();
removed_nodes++;
for (auto i : matrix[course]) {
if (--indegree[i] == 0)
q.push(i);
}
}
return removed_nodes == numCourses; //是否有环
}
DFS
Kahn算法考虑的是入度,DFS考虑出度。从0出度递推
L ← Empty list that will contain the sorted nodes
S ← Set of all nodes with no outgoing edges
for each node n in S do
visit(n)
function visit(node n)
if n has not been visited yet then
mark n as visited
for each node m with an edgefrom m to ndo
visit(m)
add n to L