bfs

作者回顾了参加NOIP2017的经历,虽然成绩不理想但受到鼓舞,决定专心提升算法水平。近期状态颇佳,在图搜索算法BFS上取得了显著进步,并分享了三段BFS相关的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习.

第一次写博客非常开心了!!

作为一个蒟蒻感觉oi之路非常艰辛…

参加了noip2017,成绩出来不想说话…
老李安慰(?)我们说反正这次去只是体验一下见见题,可是听说同级林荫神犇400+!!!

真难受啊真难受…

于是打算好好学习,不想小哥哥了,不想了不想了。

这周状态异常良好,第一次上课认认真真听完了所有老李讲的东西(啊别打我啊别打我
bfs非常顺手,连着刷了10+道题

好像上周谁发空间说细胞很难于是试了一下,五分钟一次过。

以此纪念我爱的bfs。


#include<bits/stdc++.h>
#define up(i,m,n) for(int i=m;i<n;i++) 
using namespace std;

const int zl[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
const int maxn=105,maxm=10005;

int xqd,yqd,xzd,yzd,n,m; 
char maze[maxn][maxn];

struct node{
    int x,y,s;
    node():x(),y(),s(){}
    node(const int x,const int y,const int s):
    x(x),y(y),s(s){}
};node q[maxm];

void bfs()
{
    int head=0,tail=1;
    q[tail]=node(xqd,yqd,0);
    maze[xqd][yqd]='#';
    while(head<tail){
        head++;
        node b=q[head];
        up(i,0,4){
            int xx=b.x+zl[i][0],yy=b.y+zl[i][1];
            if(xx>=0&&xx<m&&yy>=0&&yy<n&&maze[xx][yy]!='#'){
                q[++tail]=node(xx,yy,b.s+1);
                maze[xx][yy]='#';
            }
            if(xx==xzd&&yy==yzd){
                printf("%d",q[tail].s);
                return ;
            }
        }
    }
}

int main()
{
    cin>>m>>n;
    up(i,0,m)
      scanf("%s",maze[i]);
    up(i,0,m)
      up(j,0,n){
        if(maze[i][j]=='S'){
            xqd=i;yqd=j;
        }
        if(maze[i][j]=='T'){
            xzd=i;yzd=j;
        }  
      }
    bfs();
    return 0;
}
走出迷宫

最简单的迷宫问题,关于最短路径。


#include<cstdio>
#include<iostream>
using namespace std;

int zl[4][2]={{0,-1},{0,1},{1,0},{-1,0}};

char cell[105][105];
int q1[100],q2[100],num=0,n,m;

void bfs(int w,int z)
{
    int head=0,tail=1;
    q1[tail]=w;
    q2[tail]=z;
    cell[w][z]='0';
    num++;
    while(head<tail){
        head++;
        int x=q1[head],y=q2[head];
        for(int i=0;i<4;i++){
            int xx=x+zl[i][0],yy=y+zl[i][1];
            if(xx>=0&&xx<m&&yy>=0&&yy<n&&cell[xx][yy]!='0'){
                tail++;
                q1[tail]=xx;
                q2[tail]=yy;
                cell[xx][yy]='0';
            }
        }
    }

}

int main()
{
    cin>>m>>n;
    for(int i=0;i<m;i++)
      scanf("%s",cell[i]);
    for(int i=0;i<m;i++)
        for(int j=0;j<n;j++)
            if(cell[i][j]!='0')
                bfs(i,j);
    printf("%d",num);
}
细胞

嘻嘻。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn=105,maxm=100005;
const int zl[6][3]={{0,1,0},{0,-1,0},{1,0,0},{-1,0,0},{0,0,1},{0,0,-1}};

char maze[maxn][maxn][maxn];
int m,n,h,xzd,yzd,zzd,zqd,xqd,yqd;

struct node{
    int x,y,z,s;
    node():x(),y(),z(),s(){}
    node(const int x,const int y,const int z,const int s):
    x(x),y(y),z(z),s(s){}
};
node q[maxm]; 

void bfs(int x,int y,int z)
{
    int head=0,tail=1;
    q[tail]=node(x,y,z,0);
    maze[z][x][y]='#';
    while(head<tail){
        head++;
        node b=q[head];
        for(int i=0;i<6;i++){
            int xx=b.x+zl[i][0],yy=b.y+zl[i][1],zz=b.z+zl[i][2];
            if(xx>=1&&xx<=m&&yy>=0&&yy<n&&zz>=1&&zz<=h
               &&maze[zz][xx][yy]!='#'){
                    maze[zz][xx][yy]='#';
                    q[++tail]=node(xx,yy,zz,b.s+1);
               }
            if(xx==xzd&&yy==yzd&&zz==zzd){
                printf("Escaped in %d minute(s).\n",q[tail].s);
                return ;
            }
        }
    }
    printf("Trapped!\n");
}

int main()
{
    while(cin>>h>>m>>n){
        if(!m&&!n&&!h) break;
        for(int i=1;i<=h;i++)
          for(int j=1;j<=m;j++)
            scanf("%s",maze[i][j]);
        for(int i=1;i<=h;i++)
          for(int j=1;j<=m;j++)
            for(int k=0;k<n;k++){
                if(maze[i][j][k]=='S'){
                    zqd=i;xqd=j;yqd=k;
                }
                if(maze[i][j][k]=='E'){
                    zzd=i;xzd=j;yzd=k;
                }
            }
        bfs(xqd,yqd,zqd);
    }
    return 0;
}
Dungeon Master

一个三维迷宫,一开始运行全都是trapped,neng死没找到错,后来发现字符串都是从0开始读入的啊..记住了记住了!!


其他的没什么意思,感觉都差不多,那就这样吧嘿嘿嘿。

写博客真好玩..
2017.11.26

<think>首先,用户的问题是关于BFS(广度优先搜索)算法的实现方法和应用场景。我需要根据系统级指令来结构化我的回答。 系统级指令: 1. 行内数学表达式用$...$格式。 2. 独立公式用$$...$$格式并单独成段。 3. LaTeX语法正确。 4. 使用中文回答。 5. 生成相关问题。 6. 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 参考引用: - 引用[1]: 描述BFS算法的原理。 - 引用[2]: BFS算法思想、实现和应用场景。 - 引用[3]: BFS的限制和应用场景。 用户意图是了解BFS的实现方法和应用场景。所以,我需要覆盖: 1. BFS的基本原理。 2. BFS的实现方法(包括伪代码或代码示例)。 3. BFS的应用场景。 4. 生成相关问题。 结构我的回答: 1. **引言**:简要介绍BFS。 2. **算法原理**:解释BFS如何工作。 3. **实现方法**:提供实现细节,可能包括伪代码或代码示例。 4. **应用场景**:列出常见的应用。 5. **相关问题**:生成相关问题。 使用中文回答。 关于数学表达式:BFS不涉及太多数学,但如果有,比如在讨论图论时,确保使用正确的LaTeX格式。例如,节点、边等。 生成相关问题:在回答末尾,添加§§相关问题§§部分。 引用标识:在回答中,如果参考了引用,自然地添加[^1]等。引用是基于提供的引用内容。 提供的引用: - [^1]: BFS是图或树中的遍历算法,逐层访问。 - [^2]: BFS思想:由近至远,访问路径长度为1,2,3...的顶点,使用队列。 - [^3]: BFS限制:边权不为1时可能无法得到最短路径,建议其他算法如Dijkstra。 在我的回答中,我需要整合这些信息。 大纲回答: 1. **BFS简介**:定义BFS。 2. **算法原理**:描述BFS如何工作,使用队列,逐层遍历。 3. **实现方法**:提供伪代码或代码示例(如Python)。 4. **应用场景**:列出如迷宫求解、社交网络分析等。 5. **限制**:提到边权不为1时的限制。 6. **相关问题**:生成2-3个相关问题。 确保LaTeX:例如,在描述图时,如果有数学表达式,用$...$。但BFS通常不涉及复杂数学。 代码示例:如果提供代码,用代码块格式,如示例中的Python代码。 最终回答结构: - 清晰分段。 - 结尾添加相关问题。</think>### BFS(广度优先搜索)算法:实现方法与应用场景 BFS(广度优先搜索)是一种基础的图遍历算法,广泛应用于图或树数据结构中。它从起始节点开始,逐层向外扩展访问节点,确保先访问所有距离为1的节点,再访问距离为2的节点,依此类推。这种“由近及远”的特性使BFS在寻找最短路径(当边权为1时)和遍历连通分量时非常高效[^1]。以下我将逐步解释BFS的原理、实现方法、应用场景及限制,确保内容真实可靠(基于图论和算法领域的标准知识)。 #### 1. **BFS算法原理** BFS的核心思想是“分层遍历”。它使用一个队列(FIFO结构)来管理节点访问顺序: - **初始化**:从起始节点开始,将其加入队列并标记为已访问。 - **遍历过程**:每次从队列中取出一个节点,访问其所有未访问的邻居节点,并将这些邻居加入队列。 - **终止条件**:当队列为空时,遍历结束。 这种机制确保节点按距离起始节点的层数(即路径长度)顺序访问。例如,在图$G=(V,E)$中,起始节点$s$,BFS保证先访问所有$d(s,v)=1$的节点$v$,再访问$d(s,v)=2$的节点,其中$d$表示最短路径距离[^2]。 数学上,BFS的时间复杂度为$O(|V| + |E|)$($V$为节点集,$E$为边集),空间复杂度为$O(|V|)$(最坏情况队列存储所有节点)[^1]。 #### 2. **BFS实现方法** BFS的实现通常借助队列数据结构。以下是Python代码示例,清晰展示算法步骤: ```python from collections import deque def bfs(graph, start): visited = set() # 存储已访问节点 queue = deque([start]) # 初始化队列 visited.add(start) while queue: node = queue.popleft() # 取出队列头部节点 print(node) # 访问节点(可根据需求修改,如存储路径) for neighbor in graph[node]: # 遍历邻居 if neighbor not in visited: visited.add(neighbor) queue.append(neighbor) # 邻居入队 ``` **代码说明**: - **输入**:`graph` 是图的邻接表表示(字典形式),例如 `{'A': ['B', 'C'], 'B': ['A', 'D'], ...}`;`start` 是起始节点。 - **过程**:使用队列确保节点按层访问。每次取出节点后,检查其邻居,未访问的加入队列。 - **输出**:遍历顺序(如打印节点)。此实现适用于无向图或有向图(需调整邻居获取逻辑)。 **关键点**:BFS必须使用队列来维护访问顺序,避免递归(防止深度优先行为)[^2]。在边权为1的图中,BFS能高效找到最短路径。 #### 3. **BFS应用场景** BFS的“逐层扩展”特性使其在多个领域有广泛应用: - **迷宫求解与路径规划**:在网格地图中(如游戏AI),BFS可找到从起点到终点的最短路径(当所有移动步长为1时)[^3]。例如,在$n \times n$迷宫中,BFS保证输出最短解。 - **社交网络分析**:用于查找用户之间的“最短关系链”(如六度空间理论),通过BFS遍历朋友网络[^1]。 - **网络爬虫**:搜索引擎中,BFS用于按层级抓取网页,优先访问种子页面的直接链接[^2]。 - **连通分量检测**:在无向图中,BFS可识别所有连通区域(从起始节点扩展至不可达点)。 - **AI与游戏开发**:如棋类游戏中生成合法移动树,或检测状态可达性[^3]。 **限制**:BFS假设所有边权为1。如果边权不同(如加权图),BFS无法保证最短路径,此时应使用Dijkstra或A*算法[^3]。 #### 4. **BFS的限制与注意事项** - **边权问题**:当边权不为1时,BFS可能输出非最短路径(例如,在交通网络中距离不等)。 - **空间开销**:队列可能存储大量节点,不适合极大图(可结合迭代深化优化)。 - **适用性**:BFS仅适用于无权图或树结构;对于加权图,优先考虑其他算法[^3]。 BFS是图算法的基础,理解其原理和实现有助于掌握更高级算法(如Dijkstra)。如果您有具体图数据或场景,我可提供定制化代码分析。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值