zoukankan      html  css  js  c++  java
  • 【LeetCode】课程表

    【问题】现在你总共有 n 门课需要选,记为 0 到 n-1。

    在选修某些课程之前需要一些先修课程。例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]

    给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?

    示例 1:
    输入: 2, [[1,0]] 
    输出: true
    解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。
    示例 2:
    输入: 2, [[1,0],[0,1]]
    输出: false
    解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0;并且学习课程 0 之前,你还> 应先完成课程 1。这是不可能的。
    说明:
    
    输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法。
    你可以假定输入的先决条件中没有重复的边。

    【思路】由于本题目中的每个课程之间都有相应的联系,因此我们可以根据课程关系来构建一个有向图,如果在这个有向图中存在一个循环,那么则不能学完所有的课程,因为每个课程都需要每个先决条件的课程。一个很简单的思路是使用拓扑排序算法,可以判断一个循环是否存在于一个有向图中。

    拓扑排序算法:计算图中所有节点的入度,如果某些节点的入度为零,则压入到队列todo中,接着循环弹出队列中的节点(即入读为零的节点),同时将下一个节点中入度为零的节点压入队列中,如果最后图都可以分离开,也就在此过程中,每个节点在分离时都可能入度为零。说明这个有向图中没有循环,否则则有循环。

    拓扑排序
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
            std::unordered_map<int, int> indegree;
            for(auto& v : prerequisites) {
                indegree[v[0]]++;
            }
            queue<int> que;
            for(int i=0; i<numCourses; ++i) {
               if(indegree[i] == 0) {
                   que.push(i);
               }
            }
            int cnt = 0;
            while(!que.empty()) {
                int k = que.front();
                que.pop();
                cnt++;
                for(auto& v : prerequisites) {
                    if(k == v[1]) {
                        if(--indegree[v[0]] == 0) {
                            que.push(v[0]);
                        }
                    }
                }
            }
            if(cnt != numCourses)
                return false;
            return true;
  • 相关阅读:
    HDU 2544 最短路
    HDU 3367 Pseudoforest
    USACO 2001 OPEN
    HDU 3371 Connect the Cities
    HDU 1301 Jungle Roads
    HDU 1879 继续畅通工程
    HDU 1233 还是畅通工程
    HDU 1162 Eddy's picture
    HDU 5745 La Vie en rose
    HDU 5744 Keep On Movin
  • 原文地址:https://www.cnblogs.com/zhudingtop/p/11596387.html
Copyright © 2011-2022 走看看