广度优先搜索及其应用
Posted 算法指北
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了广度优先搜索及其应用相关的知识,希望对你有一定的参考价值。
预计阅读15min
天地不同方觉远,共天无别始知宽。
------------唐·曹松《南海》
框架1(完全版)
/*假定图G(V,E)是以邻接表储存的。
我们给每个节点赋予一些额外的属性:
u.visited 标记节点u是否访问过。
u.parent 储存u的前驱节点(可用来回溯路径),
没有前驱时parent设为NULL。
u.d用来储存从源节点到u之间的距离。*/
BFS(G,s):
1.初始化变量,对G.V-{s}中的所有节点u:
u.visited=false
u.parent=NULL
u.d=0
2.声明空队列Q
3.将s 入队 Enqueue(Q,s)
4.当Q不空时循环下述过程:
u=Dequeue(Q)//删除队头元素并返回其值给u
u.visited=true
对u 的每一个邻点v:
如果v.visited=false:
v.d=u.d+1
v.parent=u
v入队 Enqueue(Q,v)
时间复杂度:
算法只在一个节点出队的时候才对该节点的邻接表进行扫描,
每个邻接链表最多扫描一次,由于所有的长度之和是O( E),
用于扫描的总时间为O( E), 而每个节点入栈一次的总时间为O(V),
初始化操作的成本是O(V),因此总运行时间是O(V+E)
BFS(G,s)
1. 声明visited数组//用来标记哪些访问过,哪些没访问
2. 声明空队列Que
3.visited[s]=true
4.s入队,Enqueue(Que,s)
5.step=0 ,声明n用来储存每一步Que的长度
6.while(Que不空)
6.1.n=Que.length
6.2.for(int i=0;i<n;i++)//保证每次都把本层节点全部弹出
s=Dequeue(Que)
for u in adjacent[s]:
if(u==target)return step+1//遇到目标节点,返回距离
if visited[u]=false:
visited[u]=true
Enqueue(Que,u)
6.3. step=step+1
在给定的二维二进制数组 A 中, 存在两座岛。(岛是由四面相连的 1 形成的一个最大组。)
现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。返回必须翻转的 0 的最小数目。(可以保证答案至少是 1。)
示例 : 输入:[ [1,1,1,1,1], [1,0,0,0,1], [1,0,1,0,1], [1,0,0,0,1], [1,1,1,1,1]] 输出:1
class Solution {
public:
//代码块1
int shortestBridge(vector<vector<int>>& A) {
int m = A.size(), n = A[0].size();
queue<pair<int, int>> points;//用于存储遍历过的节点
// dfs寻找第一个岛屿,并把1全部赋值为2
bool flag = false; //标记是否进行过dfs遍历操作
for (int i = 0; i < m; ++i) {
if (flag) break;
for (int j = 0; j < n; ++j) {
if (A[i][j] == 1) {
//从第一个‘1’开始找到第一座岛屿的全部
//并储存在points中
dfs(points, A, i, j);
flag = true;
break;
}
}
}
//从第一个岛屿bfs
//代码块2
int step = 0;//当前距离
int dirR[4] = {-1, 0, 1, 0};//坐标跟新方向
int dirC[4] = {0, 1, 0, -1};
while (!points.empty())
{
int k = points.size();
for (int i = 0; i< k; i++)
{
auto f = points.front();
points.pop();
for (int d =0; d< 4; d++)
{
int r = dirR[d] + f.first;
int c = dirC[d] + f.second;
if (r < 0 || r >= A.size() || c < 0 || c >= A[0].size()) continue;
if (A[r][c] == 2) continue;
if (A[r][c] == 1) return step;
A[r][c] = 2;
points.push({r, c});
}
}
step++;
}
return step;
}
//代码块3
void dfs(queue<pair<int, int>>& points,vector<vector<int>>& grid,int rows,int cols){
int nr = grid.size();
int nc = grid[0].size();
grid[rows][cols] = 2;
points.push({rows,cols});
if(rows-1>=0&&grid[rows-1][cols]==1){
dfs(points,grid,rows-1,cols);
}
if(rows+1<nr&&grid[rows+1][cols]==1){
dfs(points,grid,rows+1,cols);
}
if(cols-1>=0&&grid[rows][cols-1]==1){
dfs(points,grid,rows,cols-1);
}
if(cols+1<nc&&grid[rows][cols+1]==1){
dfs(points,grid,rows,cols+1);
}
}
};
以上是关于广度优先搜索及其应用的主要内容,如果未能解决你的问题,请参考以下文章