拓扑排序学习笔记(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;
    }
};

 

 

posted @ 2021-06-20 22:46  wegret  阅读(63)  评论(0)    收藏  举报