图论之图的遍历DFS与BFS

图的遍历:从图中某个顶点出发,不重复的访遍图中所有顶点。
一、DFS深度优先遍历(一个支路一个支路的)
基本思想:
从图中某个顶点V0 出发,访问此顶点,然后依次从V0的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和V0有路径相通的顶点都被访问到。——访问标记,访问与它相连且未被访问的点,如果周围的点都被访问过了,那就后退一步。
图论之图的遍历DFS与BFS_第1张图片

//一个图的深搜
void dfs(int x)
{
    visited[x]=true;//标记x被访问
    for(int i=0;i//g[x].size()表示与x相连的点的个数
        if(!visited[i])
            dfs(i);
    //遍历x的相邻结点,若没被访问则从这个结点开始深搜遍历
} 

图论之图的遍历DFS与BFS_第2张图片

//多个图深搜遍历
const int MAXN=1000+10;
vector<int> g[MAXN];
bool visited[MAXN];
int main()
{
    for(int i=1;i<=MAXN;i++)
        g[i].clear();
    memset(visited,0,sizeof(visited));
    //初始化清空g和visited数组
    for(int i=1;i<=MAXN;i++)
        if(!visited[i])
            dfs(i);
} //只执行了每个图的顶点的dfs,其他的因为visited都是1,所以不管它==

二、BFS广度优先搜索(一层一层的)
基本思想:
从某个顶点V0出发,并在访问此顶点之后依次访问V0的所有未被访问过的邻接点,之后按这些顶点被访问的先后次序依次访问它们的邻接点,直至图中所有和V0有路径相通的顶点都被访问到。
图论之图的遍历DFS与BFS_第3张图片

//第一层进去了,出来后,第二层再进去,队头元素踢出去后,相连的未被访问的进来
const int MAXN=1000+5;
queue<int> q;
bool visited[MAXN];
初始化清空:
while(!q.empty())
    q.pop();
memset(visited,0,sizeof(visited));
void bfs()
{
    visited[1]=1;//初始结点1进入队列
    q.push(1);
    while(!q.empty())//队列为空时结束遍历
    {
        int t=q.front();
        q.pop();
    //寻找队头元素的相邻结点并弹出对头元素
        for(int i=0;iif(!visited[i])
            {
                q.push(i);
                visited[i]=1;
            //访问相邻结点并使之入队
            }
    }
}

三、tips
1.用DFS求连接块,通过递归实现;用BFS求最短路,通过队列实现。
2.很多复杂的迷宫问题都可以转化为最短路问题,然后用BFS求解。
(1)在套用BFS框架之前,要先搞清楚图中的“结点”包括哪些内容。
(2)用BFS求出最短路后,可以用递归打印最短路的具体路径。
(3)如果最短路非常长,递归可能会引起栈溢出,此时可以改用循环,用vector保存路径。

你可能感兴趣的:(图论)