vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
        
        vector<int> result;
        vector<int> enterance (numCourses, true);
        
        //using map to stroe the graph, it's easy to search the edge for each node
        //the bool in pair means it is explored or not
        unordered_map<int, vector<int>> graph;
        for(int i=0; i<prerequisites.size(); i++){
            graph[prerequisites[i].first].push_back( prerequisites[i].second );
            enterance[prerequisites[i].second] = false;
        }

        //explored[] is used to record the node already checked!
        vector<int> explored(numCourses, false);

        //path[] is used to check the cycle during DFS
        vector<int> path(numCourses, false);

        for(int i=0; i<numCourses; i++){
            if (!enterance[i] || explored[i]) continue;
            if (!topologicalSort(i, explored, path, graph, result)) return result;
        }
        //if there has one course hasn't been explored, means there is a cycle
        for (int i=0; i<numCourses; i++){
            if (!explored[i]) return vector<int>();
        }
        return result;
    }
Exemplo n.º 2
0
// - Job is to fill out the "scc" with leaders and followers vector
// - Note! Vertices should now be labeled by "finishing time"
void dfsLoopPost( const vector<Node> &g, vector<SCC> &scc, const vector<long> &ftLookUp )
{
    long len = g.size();
    
    //Flags whether or not a vertex has been explored
    vector<bool> explored(len, false);
    
    //Keeps track of beginning of vertex of DFS
    long s = 0;
    
    //Loop through the finishing times in reverse order
    for( long ft = len - 1; ft >= 0; --ft )
    {
        //If the vertex corresponding to that ft hasn't been explored,
        if ( !(explored[ ftLookUp[ft] ]) )
        {
            //Set s as this element and add an SCC to scc
            s = ftLookUp[ ft ];
            SCC emptySCC;
            scc.push_back(emptySCC);
            scc[ scc.size() - 1 ].leader = s;
            
            //Run a DFS starting from that vertex
            dfsPost( g, ftLookUp[ ft ], s, explored, scc, ftLookUp );
        }
    }
}
  RandomWalkGenerator::Statistics measure(Graph& graph,uint_fast32_t initial_order){
    RandomWalkGenerator::Statistics statistics;

    // Run a BFS on the graph, ignoring the initial_order edges
    // Starting in each one of those
    std::vector<bool> explored(graph.order(),false);
    std::queue<VerticeDepth> queue;

    for(uint_fast32_t start = 0; start < initial_order; start++){
      queue.push({start, 0});
      explored[start] = true;
    }

    while(!queue.empty()){
      auto curr = queue.front();
      queue.pop();

      // Documentar melhor porque foi dificil de explicar
      if(curr.depth >= statistics.vertices_per_depth.size()){
        statistics.vertices_per_depth.push_back(1);
      } else {
        statistics.vertices_per_depth[curr.depth]++;
      }

      for(auto n : *graph.neighbors_of(curr.vertice)) {
        if(!explored[n]){
          queue.push({n, curr.depth+1});
          explored[n] = true;
        }
      }
    }

    statistics.degree_distribution = graph.degree_distribution();
    return statistics;
  }
Exemplo n.º 4
0
std::vector<int> get_order(std::vector< std::vector<int> > &neighbors)
{
	std::vector<int> order( neighbors.size(), 0);
	std::queue<int> next_nodes;
	int nodes_visited = 0;
	std::vector<bool> explored(neighbors.size(),false);
	int i = 0,j=0;
	while(nodes_visited < neighbors.size() )
	{
		while(explored[i])
		{
			i++;
		}
		next_nodes.push(i);
		explored[i] = true;
		order[nodes_visited++] = i;
		while(!next_nodes.empty())
		{
			int v = next_nodes.front();
			next_nodes.pop();
			for(int k = 0 ; k < neighbors[v].size() ; k++)
			{
				int w = neighbors[v][k];
				if(!explored[w])
				{
					explored[w] = true;
					order[nodes_visited++] = w;
					next_nodes.push(w);
				}
			}
		}
		j++;
	}
	return order;
}
Exemplo n.º 5
0
std::vector<Graph::Edge> prim(const Graph& G)
{
    auto n = G.num_vertices();

    std::vector<Edge> T;
    if (n < 2)
        return T;

    Vertex num_tree_edges = n - 1;

    T.reserve(num_tree_edges);

    std::vector<char> explored(n, false);

    std::priority_queue<Edge, std::vector<Edge>, by_reverse_weight>
      EdgesToExplore;

    explored[0] = true;
    for (auto v : G.neighbors(0))
    {
        EdgesToExplore.emplace(0, v, v.weight());
    }

    while (!EdgesToExplore.empty())
    {
        Edge s = EdgesToExplore.top();
        EdgesToExplore.pop();

        if (explored[s.to])
            continue;

        T.emplace_back(s);

        --num_tree_edges;
        if (num_tree_edges == 0)
            return T;

        explored[s.to] = true;
        for (auto v : G.neighbors(s.to))
        {
            if (!explored[v])
                EdgesToExplore.emplace(s.to, v, v.weight());
        }
    }
    return T;
}
Exemplo n.º 6
0
void dfsLoopPre( const vector<Node> &g, vector<long> &ftLookUp )
{
    long len = g.size();
    
    //Flags whether or not a vertex has been explored
    vector<bool> explored(len, false);
    
    // - Keeps track of the "finishing time" for each node
    // - The first vertex at the end of a DFS is given t = 0
    // - The last vertex is give t = len - 1
    long t = 0;
    
    //Loop through the vertices in reverse order
    //(I don't think reverse order matters here)
    for( long i = len - 1; i >= 0; --i )
    {
        //If the vertex hasn't been explored,
        if ( !(explored[ i ]) )
        {
            //Run a DFS starting from that vertex
            dfsPre( g, i, t, explored, ftLookUp );
        }
    }
}