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;
       }
    };
  • 相关阅读:
    poj 3243 Clever Y(BabyStep GiantStep)
    poj 2417 Discrete Logging
    poj 3481 Double Queue
    hdu 4046 Panda
    hdu 2896 病毒侵袭
    poj 1442 Black Box
    hdu 2815 Mod Tree
    hdu 3065 病毒侵袭持续中
    hdu 1576 A/B
    所有控件
  • 原文地址:https://www.cnblogs.com/crazyacking/p/5283462.html
Copyright © 2011-2022 走看看