[拓扑排序]leetcode207:课程表(medium)

题目:
在这里插入图片描述
题解:

  • 拓扑排序裸题
  • 算法步骤:
  • 1)遍历边的数组prerequisites建立图的邻接表
  • 2)使用队列来存放入度为0的顶点,从而避免重复检测入度为0的顶点
  • 3)删除入度为0的点,以及删除该点为起点的边,并统计删除入度为0的顶点个数
  • 4)若有向图无环,则count等于顶点数numCounses;否则有向图有环,则count会小于顶点数numCounses

拓扑排序算法思路:

  • 1)在有向图中选一个入度为0的顶点且输出之
  • 2)从图中删除该顶点和所有以它为弧尾的弧
  • 3)重复上述两步,直至全部顶点均已输出,或者当前图中不存在无前驱的顶点为止。=后者表示的是该有向图存在环

代码如下:

class Solution {
public:
    //题解:拓扑排序判断有向图是否存在环即可,当然这就是拓扑排序的主要作用
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        map<int,set<int>> adjacent;//邻接表
        vector<int> indegree(numCourses);//存放顶点入度的数组
        //1、遍历图的边,建立邻接表和存放顶点入度的数组
        for(auto& edge:prerequisites){
            int a=edge[0],b=edge[1];
            adjacent[a].insert(b);
            ++indegree[b];
        }
        //2、使用队列来存放入度为0的顶点,从而避免重复检测入度为0的顶点
        queue<int> todo;
        for(int i=0;i<numCourses;++i){
            if(!indegree[i])todo.push(i);
        }
        //3、删除入度为0的点,以及删除该点为起点的边,并统计删除入度为0的顶点个数
        int count=0;
        while(!todo.empty()){
            auto v=todo.front();//入度为0的顶点
            todo.pop();
            ++count;
            auto & adjs=adjacent[v];//v的所有邻接点,即弧头为v所有弧的弧尾
            //对v号顶点的每个邻接点的入度减1,若入度为0了,则加入队列中
            for(auto adj:adjs){
                --indegree[adj];
                if(!indegree[adj])todo.push(adj);
            }
        }
        //4、若有向图无环,则count等于顶点数numCounses;否则有向图有环,则count会小于顶点数numCounses
        return count==numCourses;
    }
};
发布了512 篇原创文章 · 获赞 175 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_43152052/article/details/104345925