DFS/BFS-整理

DFS问题的类型
一般看到连通块就是用DFS,不同的是需要用连通块的什么信息

如果问有多少个连通块?<=> 调用几次DFS,一般就是主函数里的dfs函数被调用的次数,在这个情况下,就需要对每个点属于哪个连通分量进行记录(用二维数组)

如果问一个连通块有多少块?<=> 做完一遍DFS有多少点被标记,可以做完一次DFS就可以知道,在DFS函数中,对访问过的点标记(用二维数组)
或者直接定义一个全局变量

以上两种标记只需要用一个二维数组,如果是有几个连通分量的话,只需要每次主函数调用DFS的时候,传一个数值作为这个连通分量的标记,这样DFS函数中,一个连通分量的点都用这个相同的数字标识;如果只需要记录一个连通分量有几个点,就直接记录0还是1即可

忽然想到的一些别的点
1>.用while的时候,如果每次是一个新的case,那么while里面一定要先初始化

2>.if(m=n)把n的值赋给m,返回的是m的值,只要n不为0,那么就是true

DFS存图
一般用二维数组
一个二维数组存图的内容
一个二维数组存这个点是不是被访问过

怎么走遍所有点
如果是上下左右的话:

int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};

for(int i=0;i<4;i++)
{
	x=x+dx[i];
	y=y+dy[i];
}
如果是八个方向就对应再加上四个

主函数中调用d的DFS

声明全局变量
int idx[m][n];//记录点是都访问过的二维数组
int cnt;//连通分量的标记

  for(int i=0;i<m;i++)
	  for(int j=0;j<n;j++)
	  {
		  if(idx[i][j]===0&&题目要求,什么样的点可以访问)
		  {
			  cnt++;
			  dfs(i,j,cnt);//在fds函数中,访问过的点就赋值cnt,表示属于同一个连通分量,连通分量的编号是cnt
			  }
	}

DFS函数

void dfs(int r,int c,int id)//如果只是记录一个连通分量有几个点,不需要第三个参数
{
	if(r<0||r>=m||c<0||c>=n) return;//首先判断这个点是不是超过图的边界了
	if(idx[r][c]>0||不是可以走通的点) return ;//如果已经访问过,或者走不通
	//如果上面两个条件都不是,说明这个点是连通分量中的点
	标记上idx[r][c]=id;
	for(int i=0;i<4;i++)
		dfs(r+dx[i],c+dy[i],id);
}

BFS问题的类型
天然可以解决最短路的问题:(因为它首先走到的是一步可以走到的点)
每个点用结构体来定义:位置,和走到这个点的步数

BFS过程的实现上
一般定义结构体表示每个节点

是不是访问过,一般开一个数组存放,而不会放在BFS的结构体里面

初始点入队
判断队列不为空
{
出队一个点
遍历这个点的所有相邻的点,遍历的方法和DFS一样
,判断这些点是否可以走,把这些点要记录的内容算出
如果可以走,把这个点入队
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值