bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) { if(numCourses <= 0) return false; vector<unordered_set<int> > forward_map(numCourses); for(int i = 0; i < prerequisites.size(); ++i) { forward_map[prerequisites[i].second].insert(prerequisites[i].first); } unordered_set<int> visited; vector<bool> flag(numCourses, false); for(int i = 0; i < numCourses; ++ i) if(!flag[i]) if(dfs(forward_map, visited, i, flag)) return false; return true; }
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) { if(numCourses <= 0) return false; vector<unordered_set<int> > forward_map(numCourses); for(int i = 0; i < prerequisites.size(); ++i) { forward_map[prerequisites[i].second].insert(prerequisites[i].first); } vector<bool> perm_visit(numCourses, false); for(int i = 0; i < numCourses; ++i) { if(perm_visit[i] == false) { vector<bool> temp_visit(numCourses,false); if(dfs(forward_map, i, temp_visit, perm_visit)) { return false; } } } return true; }
//BFS solution bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) { if(numCourses <= 0) return false; vector<unordered_set<int> > forward_map(numCourses); vector<int> indegree(numCourses,0); for(int i = 0; i < prerequisites.size(); ++i) { forward_map[prerequisites[i].second].insert(prerequisites[i].first); } for(int i = 0; i < forward_map.size(); ++i) { for(auto it:forward_map[i]) { ++indegree[it]; } } for(int i = 0; i < numCourses; ++i) { int k; for(k = 0; k < numCourses && indegree[k] != 0; ++k); if(k == numCourses) return false; indegree[k] = -1; for(auto it:forward_map[k]) { --indegree[it]; } } return true; }
// ------------------------------------------------------------ // SFCPartitioner implementation void SFCPartitioner::_do_partition (MeshBase & mesh, const unsigned int n) { libmesh_assert_greater (n, 0); // Check for an easy return if (n == 1) { this->single_partition (mesh); return; } // What to do if the sfcurves library IS NOT present #ifndef LIBMESH_HAVE_SFCURVES libmesh_here(); libMesh::err << "ERROR: The library has been built without" << std::endl << "Space Filling Curve support. Using a linear" << std::endl << "partitioner instead!" << std::endl; LinearPartitioner lp; lp.partition (mesh, n); // What to do if the sfcurves library IS present #else LOG_SCOPE("sfc_partition()", "SFCPartitioner"); const dof_id_type n_active_elem = mesh.n_active_elem(); const dof_id_type n_elem = mesh.n_elem(); // the forward_map maps the active element id // into a contiguous block of indices std::vector<dof_id_type> forward_map (n_elem, DofObject::invalid_id); // the reverse_map maps the contiguous ids back // to active elements std::vector<Elem *> reverse_map (n_active_elem, libmesh_nullptr); int size = static_cast<int>(n_active_elem); std::vector<double> x (size); std::vector<double> y (size); std::vector<double> z (size); std::vector<int> table (size); // We need to map the active element ids into a // contiguous range. { MeshBase::element_iterator elem_it = mesh.active_elements_begin(); const MeshBase::element_iterator elem_end = mesh.active_elements_end(); dof_id_type el_num = 0; for (; elem_it != elem_end; ++elem_it) { libmesh_assert_less ((*elem_it)->id(), forward_map.size()); libmesh_assert_less (el_num, reverse_map.size()); forward_map[(*elem_it)->id()] = el_num; reverse_map[el_num] = *elem_it; el_num++; } libmesh_assert_equal_to (el_num, n_active_elem); } // Get the centroid for each active element { // const_active_elem_iterator elem_it (mesh.const_elements_begin()); // const const_active_elem_iterator elem_end(mesh.const_elements_end()); MeshBase::element_iterator elem_it = mesh.active_elements_begin(); const MeshBase::element_iterator elem_end = mesh.active_elements_end(); for (; elem_it != elem_end; ++elem_it) { const Elem * elem = *elem_it; libmesh_assert_less (elem->id(), forward_map.size()); const Point p = elem->centroid(); x[forward_map[elem->id()]] = p(0); y[forward_map[elem->id()]] = p(1); z[forward_map[elem->id()]] = p(2); } } // build the space-filling curve if (_sfc_type == "Hilbert") Sfc::hilbert (&x[0], &y[0], &z[0], &size, &table[0]); else if (_sfc_type == "Morton") Sfc::morton (&x[0], &y[0], &z[0], &size, &table[0]); else { libmesh_here(); libMesh::err << "ERROR: Unknown type: " << _sfc_type << std::endl << " Valid types are" << std::endl << " \"Hilbert\"" << std::endl << " \"Morton\"" << std::endl << " " << std::endl << "Proceeding with a Hilbert curve." << std::endl; Sfc::hilbert (&x[0], &y[0], &z[0], &size, &table[0]); } // Assign the partitioning to the active elements { // { // std::ofstream out ("sfc.dat"); // out << "variables=x,y,z" << std::endl; // out << "zone f=point" << std::endl; // for (unsigned int i=0; i<n_active_elem; i++) // out << x[i] << " " // << y[i] << " " // << z[i] << std::endl; // } const dof_id_type blksize = (n_active_elem+n-1)/n; for (dof_id_type i=0; i<n_active_elem; i++) { libmesh_assert_less (static_cast<unsigned int>(table[i]-1), reverse_map.size()); Elem * elem = reverse_map[table[i]-1]; elem->processor_id() = cast_int<processor_id_type> (i/blksize); } } #endif }