拓扑排序学习笔记(leetcode 210. 课程表Ⅱ)
(两年前学过,没什么印象了,重新复习一下orz。)
拓扑排序,即在一个有向图$G$中对节点进行线性排序,使图中任意一条有向边$<u,v>$,在该序列中都满足$u$在$v$前面。
举例:

该图的拓扑序是 6,1,2,3,4,5 。
又比如:

该图的拓扑序是 1,2,3,4,7,5,6,当然也可以是 1,2,3,4,5,6,7,还可以是1,2,3,4,5,7,6。
又比如:

这图就没有拓扑序。
拓扑排序的算法不复杂。先遍历一遍所有节点,找出所有入度为0的节点加入队列。然后不断把这些点从图上删掉,加入答案(删点的同时也会产生新的入度为0的点,同样加入队列)。队列为空后,就得到了拓扑序。如果此时还有剩余的点入度不为0,那么就不存在拓扑序。
代码以 Leetcode 210.课程表Ⅱ 为例:
class Solution { public: vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) { int n=numCourses,t=prerequisites.size(); vector<int> to[n+5]; int in[n+5]; memset(in,0,sizeof(in)); for (int i=0;i<t;i++){ in[prerequisites[i][0]]++; to[prerequisites[i][1]].push_back(prerequisites[i][0]); } queue<int> que; vector<int> ans; for (int i=0;i<n;i++) if (!in[i]) que.push(i); int now; while (!que.empty()){ now=que.front(); que.pop(); ans.push_back(now); for (int i=0;i<to[now].size();i++){ in[to[now][i]]--; if (!in[to[now][i]]) que.push(to[now][i]); } } vector<int> em; return ans.size()==n?ans:em; } };


浙公网安备 33010602011771号