拓扑排序
方法一:bfs不断删除入度为0的点。见ctci p632
入度为0的节点先入队,然后出队时把它所有邻居的入度减1,并把新入度为0的节点入队。这就是bfs,因已按特定规则入队,可省略visited[]数组。
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
// 拓扑排序:不断删除入度为0的点,其实就是bfs
vector<vector<int>> graph(numCourses);
vector<int> indegree(numCourses, 0);
for (auto &edge : prerequisites) {
graph[edge[1]].push_back(edge[0]);
indegree[edge[0]]++;
}
queue<int> q;
for (int i = 0; i < numCourses; i++) {
if (indegree[i] == 0) q.push(i);
}
int count = 0;
while (!q.empty()) {
int u = q.front(); q.pop();
count++;
for (int to : graph[u]) {
if (--indegree[to] == 0) q.push(to);
}
}
return count == numCourses;
}
方法二:点的后序编号=>逆拓扑排序,即在访问完所有邻接点后、当前点进输出栈。可以从任意节点开始后序dfs,只要最外层循环把所有节点都跑一遍。