BFS从给定节点开始并到达所有节点

时间:2015-11-26 04:21:58

标签: c++ algorithm graph breadth-first-search

我有一个场景

  1. 我想从特定节点开始运行BFS(比方说ID:7)。
  2. 如果此节点无法访问节点,我想重新启动 BFS(具有任何剩余节点)直到图的所有顶点都是 访问。
  3. 到目前为止我所拥有的是从节点0开始并使用另一个未访问的顶点重新启动的代码(部分):

    void BFS()
    {
        // Mark all the vertices as not visited
        bool *visited = new bool[V];
        for(int i = 0; i < V; i++)
            visited[i] = false;
        // Call the recursive function starting from all vertices one by one
        for(int i = 0; i < V; i++)
            if(visited[i] = = false)
                BFSUtil(i,visited);
    }
    
    void BFSUtil(int s,bool *visited)
    {
        queue<int> queue;
        visited[s]=true;
        queue.push(s);
    
        while(!queue.empty())
        {
            s = queue.front();
            queue.pop();
             // Get all adjacent vertices of the dequeued vertex s
            // If a adjacent has not been visited, then mark it visited
            // and enqueue it
            for(i = adj[s].begin(); i != adj[s].end(); ++i)
            {
                if(!visited[i])
                {                
                    queue.push(i);
                    BFSUtil(id,visited);
                }
            }
        }
    
    }
    

    如何有效地更改此代码以满足我的要求?

1 个答案:

答案 0 :(得分:0)

由于您已经存储了此visited州并且排名第一,因此您已经掌握了大部分想法。要执行#2,您可以简单地遍历visited列表,查找值false以指示未访问的节点。现在在那个上运行#1。重复,直到您发现visited中的所有条目都为真。

这样的事情:

// Loop until all elements have been visited.
bool found = false;
do
{
    // Look for an element that hasn't been processed yet
    // to run the BFS.
    found = false;
    for(int i = 0; i < V; i++)
    {
        if(visited[i] = = false)
        {
            BFSUtil(i,visited);    
            found = true;
        }
    }
} while (found);

你还可以避免每次在#1之后通过visited进行线性搜索,其设置效率高于你必须线性搜索的一组布尔值,但可能需要的努力不值得努力,除非你正在搜索一大堆很小的,断开连接的图形,这通常会降低遍历的性能,除非它是一个真正有效的集合(或密集+稀疏的集合:一个用于恒定时间的快速检查,另一个有日志或更好的时间插入)。