CHAPTER_10 提高篇(4)——图算法专题
10.3.2图的遍历—BFS
用BFS遍历图,总是以“广度”作为第一关键词,每次以扩散的方式向外访问顶点。和树的BFS一样,使用BFS遍历图需要使用一个队列,通过反复取出队首顶点,将该顶点可到达的未曾加入过队列的顶点全部入队,直到队列为空时遍历结束。
我们从A开始,用BFS遍历上面这个有向图,在初始时先要将A入队。当前队列内元素为{0},取出队首元素0,访问该顶点,然后将0出队。然后将所有从A出发能到达并且还未入队的顶点都入队,即B、D、E入队。此时队列元素为{1,3,4},取出队首元素1并访问之,然后将1出队。此时B还剩一个能到达并且未入队的元素,将C入队。此时队列元素为{3,4,2},所有顶点均以入队,将队列内元素依次弹出访问即可。
实现代码(邻接表):
const int maxv=1001; //最大顶点数
vector<int> Adj[maxv]; //图的邻接表实现
int n; //图的顶点数
bool isQueue[maxv]={0}; //标志顶点是否入队
void BFS(int u) { //u为当前访问顶点
queue<int> q;
q.push(u); //将起点入队
isQueue[u]=1; //设置u已经入队
while(!q.empty()) {
int v=q.front();
q.pop(); //将队首出队
for(int i=0;I,Adj[v].size();i++) { //遍历所有从v出发能到的顶点
int vNext=Adj[v][i];
if(isQueue[vNext]==0) { //如果邻接点vNext未入队
q.push(vNext); //vNext入队
isQueue[vNext]=1; //设置已入队
}
}
}
}
void BFSTrave() {
for(int i=0;i<n;i++) { //遍历所有顶点,访问所有连通块
if(isQueue[i]==0) {
BFS(i);
}
}
}
还有一点需要注意,有时候在给定BFS初始点的情况下需要记录其他顶点的层号(类似于树的层序遍历)。我们就需要定义node数据类型存放每个顶点的层号和编号。邻接表就应定义成:
struct node {
int v; //顶点编号
int layer; //顶点层号
};
vector<node> Adj[maxv];