蓝桥杯第四次培训之图的深度遍历和广度遍历

图的遍历
图的遍历是指从图中某一个顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次
图的遍历算法是求解图的连通性问题、拓扑排序和求关键路径等算法的基础
由于图结构本身的复杂性,所以其遍历也较复杂,主要体现在:
(1)图中任意一个顶点可作为第一个被访问的顶点
(2)如何选取不同连通分量上的访问出发点
(3)图中如果有回路,可能重复访问
(4)如何选取下一个要访问的邻接点
一个图有那么多个结点,
如何遍历这些结点,需要特定策略,一般有两种访问策略:深度优先遍历、广度优先遍历
图的深度遍历
深度优先遍历,从初始访问结点出发,我们知道初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接结点。总结起来可以这样说:每次都在访问完当前结点后首先访问当前结点的第一个邻接结点。
第一步:假设初始状态是图中所有顶点均未被访问,则可以从图中某个顶点出发,访问此顶点。然后,依次从它的未被访问的邻接点出发深度优先遍历图,直至图中所有和它有路径相通的顶点均被访问到

第二步:若此时图中尚有未被访问的顶点,则另选图中一个未曾被访问的顶点作起始点。重复上述过程,直至图中所有顶点均被访问过为止
注:为了防止顶点重复访问,可为每个顶点设置一个访问标志,若等于true,则说明该顶点已被访问,顶点不得重复访问;等于false,则访问该顶点
图一
如上图所示对其进行深度遍历为:0,1,3,4,5,2
代码实现

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 100;
int a[maxn][maxn]={
    
    0};//两点时间是否连接 
bool ju[maxn]={
    
    false};//判断是否遍历成功 
int n,m;
void dfs(int x)
{
    
    
	cout<<x<<' ';
	ju[x]=true;
	for(int i=0;i<n;i++)
	{
    
    
		if(ju[i]==false&&a[x][i])//找出其邻居点且未遍历,进行遍历 
		{
    
    
		dfs(i);//遍历该点 
		}
	}
 } 
int main()
{
    
    
  fill(a[0],a[0]+maxn*maxn,0);//初始化所有边都没有连接 
  fill(ju,ju+maxn,false);//初始化所有边都未访问 
  scanf("%d %d",&n,&m);
  for(int i=0;i<m;i++)
  {
    
    
  	int x,y;//输入连接的两个点 
   scanf("%d %d",&x,&y);
    a[x][y]=1;
  }
  for(int i=0;i<n;i++)
  {
    
    
  	if(ju[i]==false)//该点是否遍历过 
  	{
    
    
  		dfs(i);//遍历该点 
	  }
  }
   return 0;
}

总结:深度搜索是一种枚举所有可能以遍历所有情况的搜索方法
练习题目:
习题一:http://codeup.cn/problem.php?cid=100000608&pid=0
习题二:http://codeup.cn/problem.php?cid=100000608&pid=1
图的广度搜索
广度遍历或广度优先搜索(BFS):类似树的层序遍历,也需要队列配合
第一步:假设初始状态是图中所有顶点均未被访问,则可以从图中某个顶点出发,访问此顶点。然后,依次遍历它的未曾遍历过的所有邻接点,并使“先被访问的顶点的邻接点” 先于 “后被访问的顶点的邻接点” 被访问,直至图中所有已被访问的顶点的邻接点均被访问到

第二步:若此时图中尚有未被访问的顶点,则另选图中一个未曾被访问的顶点作起始点。重复上述过程,直至图中所有顶点均被访问过为止

注:为了防止顶点重复访问,与深度遍历一样需要为每个顶点设置一个访问标志
在这里插入图片描述
广度搜索:0,1,2,3,4,5
代码实现

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 100;
int a[maxn][maxn]={
    
    0};
bool ju[maxn]={
    
    false};
int n,m;
queue <int> q;
void bfs()
{
    
    
	while(!q.empty())
	{
    
    
		int x=q.front();
		q.pop();
		cout<<x<<' ';
		for(int i=0;i<n;i++)
		{
    
    
			if(a[x][i]==1&&ju[i]==false)
			{
    
    
				ju[i]=true;
				q.push(i);
			}
		}
	}
}
int main()
{
    
    
   scanf("%d %d",&n,&m);
   for(int i=0;i<m;i++)
   {
    
    
   	int x,y;
   	scanf("%d %d",&x,&y);
   	a[x][y]=1;
   }
   q.push(0);
   ju[0]=true;
   bfs();
   return 0;
}

总结:广度搜索,搜索本节点相邻的所有未访问的节点,可以用队列来实现,一遍出现矩阵,搜索的题目用BFS
例题讲解:
给出一个n*m的矩阵,矩阵中的元素为0或1。称位置(x,y)与去上下左右四个位置(x,y-1),(x,y+1),(x-1,y),(x+1,y)是相邻的。如果矩阵中有若干个1是相邻的(不必两两相邻),那么就称这些1构成了一个"快"。求给定矩阵块的个数

0 1 1 1 0 0 1
0 0 1 0 0 0 0
0 0 0 0 1 0 0
0 0 0 1 1 1 0
1 1 1 0 1 0 0
1 1 1 1 0 0 0

例如上图的6*7的矩阵中,"块"的个数为4

#include <stdio.h>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 100;
int n,m;
int a[maxn][maxn];//01矩阵
bool ju[maxn][maxn];//记录是否访问
struct node{
    
    
	int x;
	int y;
};
int dx[4]={
    
    0,0,1,-1};
int dy[4]={
    
    1,-1,0,0};
bool judge(int xx,int yy)//判断该点是否可以访问
{
    
    
	if(xx<0||xx>=n||yy<0||yy>=m)
	return false;
	if(ju[xx][yy]==true||a[xx][yy]==0)
	{
    
    
		return false;
	 } 
	 return true;
}
void bfs(int xx,int yy)
{
    
    
	node no;
	no.x=xx;
	no.y=yy;
	ju[xx][yy]=true;
	queue<node> q;
	q.push(no);
	while(!q.empty())
	{
    
    
		no=q.front();
		q.pop();
		for(int i=0;i<4;i++)
		{
    
    
			node nn;
			nn.x=no.x+dx[i];
			nn.y=no.y+dy[i];
			if(judge(nn.x,nn.y))
			{
    
    
				ju[nn.x][nn.y]=true;
			q.push(nn);	
			}
		}
	}
 } 
int main()
{
    
    
  scanf("%d %d",&n,&m);
  int ans=0;
  fill(ju[0],ju[0]+maxn*maxn,false);
  for(int i=0;i<n;i++)
  {
    
    
  	for(int j=0;j<m;j++)
  	{
    
    
  		scanf("%d",&a[i][j]);
	  }
  }
  for(int i=0;i<n;i++)
  {
    
    
  	for(int j=0;j<m;j++)
  	{
    
    
  		if(a[i][j]==1&&ju[i][j]==false)
  		{
    
    
  			ans++;
  			bfs(i,j);
		  }
	  }
  }
  cout<<ans; 
   return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_45432976/article/details/113136566