zoukankan      html  css  js  c++  java
  • LeetCode 207

    一、问题描述

    Description:

    There are a total of n courses you have to take, labeled from 0 to n1.

    Some courses may have prerequisites(前提), for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

    Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

    For example:

    2, [[1,0]]

    There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.

    2, [[1,0],[0,1]]

    There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.


    二、解题报告

    这个题目就是 “排序” 具有依赖关系的课程,看是否可以上完所有的课程,等价于所有的课程是否可以进行拓扑排序

    把每个课程看做一个顶点,课程之间的依赖关系看做一条有向边,就构成了一个有向图。而该有向图能不能拓扑排序,取决于有向图中是否存在环。这部分请看《拓扑排序的C++实现

    直接上代码:

    /************************类声明************************/
    class Graph
    {
        int V;             // 顶点个数
        list<int> *adj;    // 邻接表
        queue<int> q;      // 维护一个入度为0的顶点的集合
        int* indegree;     // 记录每个顶点的入度
    public:
        Graph(int V);                   // 构造函数
        ~Graph();                       // 析构函数
        void addEdge(int v, int w);     // 添加边
        bool topological_sort();        // 拓扑排序
    };
    
    /************************类定义************************/
    Graph::Graph(int V)
    {
        this->V = V;
        adj = new list<int>[V];
    
        indegree = new int[V];  // 入度全部初始化为0
        for(int i=0; i<V; ++i)
            indegree[i] = 0;
    }
    
    Graph::~Graph()
    {
        delete [] adj;
        delete [] indegree;
    }
    
    void Graph::addEdge(int v, int w)
    {
        adj[v].push_back(w); 
        ++indegree[w];
    }
    
    bool Graph::topological_sort()
    {
        for(int i=0; i<V; ++i)
            if(indegree[i] == 0)
                q.push(i);         // 将所有入度为0的顶点入队
    
        int count = 0;             // 计数,记录当前已经输出的顶点数 
        while(!q.empty())
        {
            int v = q.front();      // 从队列中取出一个顶点
            q.pop();
    
            //cout << v << " ";      // 输出该顶点
            ++count;
            // 将所有v指向的顶点的入度减1,并将入度减为0的顶点入栈
            list<int>::iterator beg = adj[v].begin();
            for( ; beg!=adj[v].end(); ++beg)
                if(!(--indegree[*beg]))
                    q.push(*beg);   // 若入度为0,则入栈
        }
    
        if(count < V)
            return false;           // 没有输出全部顶点,有向图中有回路
        else
            return true;            // 拓扑排序成功
    }
    
    
    class Solution {
    public:
        bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
    
            Graph g(numCourses);  // 创建图
            for(int i=0; i<prerequisites.size(); ++i)
                g.addEdge(prerequisites[i][1], prerequisites[i][0]);
    
            return g.topological_sort();
        }
    };







    LeetCode答案源代码:https://github.com/SongLee24/LeetCode

  • 相关阅读:
    第十一节 CSS引入的三种方式
    第十节 表单
    第九节 页面布局(简历)
    第八节 HTML表格
    第七节 列表标签
    第六节 链接标签
    第五节 插入图的img标签
    WordPress 全方位优化指南(下)
    Cloud Insight!StatsD 系监控产品新宠!
    WordPress 全方位优化指南(上)
  • 原文地址:https://www.cnblogs.com/songlee/p/5738074.html
Copyright © 2011-2022 走看看