zoukankan      html  css  js  c++  java
  • LeetCode

    207. Course Schedule 

    Problem's Link

     ----------------------------------------------------------------------------

    Mean: 

    给定一个有向图,判断是否存在top_sort序列.

    analyse:

    转换为:判断是否存在环.

    若存在环,肯定不能找到top_sort序列.

    判环的方式有很多:SPFA,top_sort,BFS,DFS...随便选一种就行.

    Time complexity: O(N)

     

    view code

     我的代码:

    /**
    * -----------------------------------------------------------------
    * Copyright (c) 2016 crazyacking.All rights reserved.
    * -----------------------------------------------------------------
    *       Author: crazyacking
    *       Date  : 2016-03-16-09.31
    */
    #include <queue>
    #include <cstdio>
    #include <set>
    #include <string>
    #include <stack>
    #include <cmath>
    #include <climits>
    #include <map>
    #include <cstdlib>
    #include <iostream>
    #include <bits/stdc++.h>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long(LL);
    typedef unsigned long long(ULL);
    const double eps(1e-8);

    class Solution
    {
    public:
       bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites)
       {
           unordered_map<int,vector<int>> graph;
           build_graph(prerequisites,graph);
           unordered_set<int> zero;
           vector<int> in_degree(numCourses,0);
           count_degree(graph,zero,in_degree);

           while(zero.size()>0)
           {
               int cur=*zero.begin();
               zero.erase(cur);
               for(auto ptr:graph[cur])
               {
                   --in_degree[ptr];
                   if(!in_degree[ptr])
                       zero.insert(ptr);
               }
           }
           for(auto ptr:in_degree)
               if(ptr>0) return false;
           return true;
       }
       void build_graph(auto prerequisites,auto& graph)
       {
           for(auto ptr:prerequisites)
               graph[ptr.second].push_back(ptr.first);
       }
       void count_degree(auto graph,auto& zero,auto& in_degree)
       {
           for(auto ptr1:graph)
               for(auto ptr2:ptr1.second)
                   ++in_degree[ptr2];
           for(int i=0;i<in_degree.size();++i)
               if(!in_degree[i]) zero.insert(i);
       }
    };

    int main()
    {
       int num,n;
       while(cin>>num>>n)
       {
           vector<pair<int, int>> prerequisites(n);
           for(int i=0;i<n;++i)
               cin>>prerequisites[i].first>>prerequisites[i].second;
           Solution solution;
           bool res=solution.canFinish(num,prerequisites);
           if(res) cout<<"Yes."<<endl;
           else cout<<"No."<<endl;
       }
       return 0;
    }
    /*

    */

    下面是discuss区的代码,看了一下,感觉还有很多可以优化的地方,我在代码中注释出来了.

    代码1:

    bool canFinish(int numCourses, vector<vector<int>>& prerequisites)
    {
       /**< matrix的第二维没必要用unordered_set,因为不管用不用hash都得扫一遍,用hash反而更慢 */
       vector<unordered_set<int>> matrix(numCourses); // save this directed graph
       for(int i = 0; i < prerequisites.size(); ++ i)
           matrix[prerequisites[i][1]].insert(prerequisites[i][0]);

       vector<int> d(numCourses, 0); // in-degree
       for(int i = 0; i < numCourses; ++ i)
           for(auto it = matrix[i].begin(); it != matrix[i].end(); ++ it)
               ++ d[*it];

       for(int j = 0, i; j < numCourses; ++ j)
       {
           /**< 这儿可以动态维护一个set,存放入度为0的结点,就不必每次都从头开始找了 */
           for(i = 0; i < numCourses && d[i] != 0; ++ i); // find a node whose in-degree is 0

           if(i == numCourses) // if not find
               return false;

           d[i] = -1;
           for(auto it = matrix[i].begin(); it != matrix[i].end(); ++ it)
               -- d[*it];
       }
       return true;
    }

     代码2:

    class Solution
    {
    public:
       bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites)
       {
           /**< matrix的第二维没必要用unordered_set,因为不管用不用hash都得扫一遍,用hash反而更慢 */
           vector<unordered_set<int>> graph = make_graph(numCourses, prerequisites);
           vector<int> degrees = compute_indegree(graph);
           for (int i = 0; i < numCourses; i++)
           {
               int j = 0;
               /**< 这儿可以动态维护一个set,存放入度为0的结点,就不必每次都从头开始找了 */
               for (; j < numCourses; j++)
                   if (!degrees[j]) break;
               if (j == numCourses) return false;
               degrees[j] = -1;
               for (int neigh : graph[j])
                   degrees[neigh]--;
           }
           return true;
       }
    private:
       vector<unordered_set<int>> make_graph(int numCourses, vector<pair<int, int>>& prerequisites)
       {
           vector<unordered_set<int>> graph(numCourses);
           for (auto pre : prerequisites)
               graph[pre.second].insert(pre.first);
           return graph;
       }
       vector<int> compute_indegree(vector<unordered_set<int>>& graph)
       {
           vector<int> degrees(graph.size(), 0);
           for (auto neighbors : graph)
               for (int neigh : neighbors)
                   degrees[neigh]++;
           return degrees;
       }
    };
  • 相关阅读:
    Tomcat卸载重装后重装后出现的无法启动的问题
    主页面刷新 illegalStateException:stream
    JVM内存管理机制
    Java代码操作SVN
    FilenameFilter总结
    Java四种引用解析以及在Android的应用
    关于java中MD5加密(可直接使用)
    学习Java有没有什么捷径?
    深入分析java传参
    Java发展前景与职业方向解析
  • 原文地址:https://www.cnblogs.com/crazyacking/p/5283462.html
Copyright © 2011-2022 走看看