1.广度优先遍历定义
图的广度优先遍历BFS算法是一个分层搜索的过程,和树的层序遍历算法类同,它也需要一个
队列以保持遍历过的顶点顺序,以便按出队的顺序再去访问这些顶点的邻接顶点。
2.基本实现思想
(1)顶点v入队列。
(2)当队列非空时则继续执行,否则算法结束。
(3)出队列取得队头顶点v;访问顶点v并标记顶点v已被访问。
(4)查找顶点v的第一个邻接顶点col。
(5)若v的邻接顶点col未被访问过的,则col入队列。
(6)继续查找顶点v的另一个新的邻接顶点col,转到步骤(5)。直到顶点v的所有未被访问过
的邻接点处理完。转到步骤(2)。
广度优先遍历图是以顶点v为起始点,由近至远,依次访问和v有路径相通而且路径长度为1,2,……
的顶点。为了使“先被访问顶点的邻接点”先于“后被访问顶点的邻接点”被访问,需设置队列存储访
问的顶点。
3.伪代码
(1)初始化队列Q;visited[n]=0;
(2)访问顶点v;visited[v]=1;顶点v入队列Q;
(3) while(队列Q非空)
v=队列Q的对头元素出队;
w=顶点v的第一个邻接点;
while(w存在)
如果w未访问,则访问顶点w;
visited[w]=1;
顶点w入队列Q;
w=顶点v的下一个邻接点。
/*使用BFS的非递归算法:
1,判断当前队列非空并且不是终点,继续循环;
2,获取队头信息,四个方向进行判断,push;
3,flag置为false;
4,pop
*/
4,例题:
(1)题目星图 :
在给出的二维数组中,1代表星星,0代表空,找出有多少个星团(上下左右相连的算在一个星团内,45度角相连不算),并且最大的星团内有多少个星星数
[Input]
There can be more than one test case in the input.
The first line has T, the number of test cases.
Then the totally T test cases are provided in the following lines (T<=10)
In each test case, the first line has an integer N(5 ≤ N ≤ 25), the size of map.
The map is a square, and is represented as N x N matrix.
For next N lines, each contains each raw of the matrix
[Output]
For each test case, you should print the number of constellation and the number of starts in the greatest constellation separated by blank.
[I/O Example]
Input
2
7
0 1 1 0 0 0 0
0 1 1 0 1 0 0
1 1 1 0 1 0 1
0 0 0 0 1 1 1
1 0 0 0 0 0 0
0 1 1 1 1 1 0
0 1 0 1 1 0 0
5
0 1 0 0 0
0 1 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
Output
4 8
1 3
图的广度优先遍历BFS算法是一个分层搜索的过程,和树的层序遍历算法类同,它也需要一个
队列以保持遍历过的顶点顺序,以便按出队的顺序再去访问这些顶点的邻接顶点。
2.基本实现思想
(1)顶点v入队列。
(2)当队列非空时则继续执行,否则算法结束。
(3)出队列取得队头顶点v;访问顶点v并标记顶点v已被访问。
(4)查找顶点v的第一个邻接顶点col。
(5)若v的邻接顶点col未被访问过的,则col入队列。
(6)继续查找顶点v的另一个新的邻接顶点col,转到步骤(5)。直到顶点v的所有未被访问过
的邻接点处理完。转到步骤(2)。
广度优先遍历图是以顶点v为起始点,由近至远,依次访问和v有路径相通而且路径长度为1,2,……
的顶点。为了使“先被访问顶点的邻接点”先于“后被访问顶点的邻接点”被访问,需设置队列存储访
问的顶点。
3.伪代码
(1)初始化队列Q;visited[n]=0;
(2)访问顶点v;visited[v]=1;顶点v入队列Q;
(3) while(队列Q非空)
v=队列Q的对头元素出队;
w=顶点v的第一个邻接点;
while(w存在)
如果w未访问,则访问顶点w;
visited[w]=1;
顶点w入队列Q;
w=顶点v的下一个邻接点。
/*使用BFS的非递归算法:
1,判断当前队列非空并且不是终点,继续循环;
2,获取队头信息,四个方向进行判断,push;
3,flag置为false;
4,pop
*/
4,例题:
(1)题目星图 :
在给出的二维数组中,1代表星星,0代表空,找出有多少个星团(上下左右相连的算在一个星团内,45度角相连不算),并且最大的星团内有多少个星星数
[Input]
There can be more than one test case in the input.
The first line has T, the number of test cases.
Then the totally T test cases are provided in the following lines (T<=10)
In each test case, the first line has an integer N(5 ≤ N ≤ 25), the size of map.
The map is a square, and is represented as N x N matrix.
For next N lines, each contains each raw of the matrix
[Output]
For each test case, you should print the number of constellation and the number of starts in the greatest constellation separated by blank.
[I/O Example]
Input
2
7
0 1 1 0 0 0 0
0 1 1 0 1 0 0
1 1 1 0 1 0 1
0 0 0 0 1 1 1
1 0 0 0 0 0 0
0 1 1 1 1 1 0
0 1 0 1 1 0 0
5
0 1 0 0 0
0 1 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
Output
4 8
1 3
(2)解答:
//BFS
#include <stdio.h>
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
typedef struct node
{
int x;
int y;
}Node;
queue<Node> q;
int N;
int data[26][26];
int vis[26][26];
int move[4][2]={-1,0,0,1,1,0,0,-1};
int tmpC;
int BFS(int x,int y)
{
Node n;
Node tmp;
int i,j;
n.x=x;
n.y=y;
q.push(n);
vis[x][y]=1;
while(!q.empty())
{
n=q.front();
for(i=0;i<4;i++)
{
tmp.x=n.x+move[i][0];
tmp.y=n.y+move[i][1];
if(tmp.x>0 && tmp.x<=N &&
tmp.y>0 && tmp.y<=N &&
vis[tmp.x][tmp.y]==0 &&
data[tmp.x][tmp.y]==1)
{
q.push(tmp);
vis[tmp.x][tmp.y]=1;
}
}
q.pop();
tmpC++;
data[n.x][n.y]=0;
}
return 0;
}
int main(void)
{
int test_case;
int T;
freopen("sample_input.txt", "r", stdin);
setbuf(stdout, NULL);
scanf("%d", &T);
for(test_case = 0; test_case < T; test_case++)
{
int i,j;
int S,C;
scanf("%d", &N);
for(i=1; i<=N; i++) {
for(j=1; j<=N; j++) {
scanf("%d", &data[i][j]);
}
}
if(!q.empty())
q.pop();
S = 0;
C = 0;
memset(vis,0,sizeof(vis));
for(i=1;i<=N;i++)
{
for(j=1;j<=N;j++)
{
tmpC=0;
if(data[i][j]==1)
{
BFS(i,j);
S++;
if(tmpC>C)
C=tmpC;
}
}
}
// Print the answer to standard output(screen).
printf("%d %d\n", S, C);
}
return 0;//Your program should return 0 on normal termination.
}