zoukankan      html  css  js  c++  java
  • bfs初学

    BFS:

    ** 当知道初始和目标状态的,用双向BFS:
    无权图最好用BFS
    不用重复如队**

    实现框架:

    抄来的(来源:https://www.luogu.org/blog/stephen2333/solution-p1135)
    ps: 我一开始也写过,不过真心觉得他写的好

    1. 对于初始状态入队,设置初始状态为已访问
    2. 如果队列不为空时,出队队头元素,否则跳到第5步
    3. 检查出队的元素是否为最终解,如果是则跳到第5步。
    4. 对于出队的元素,检查所有相邻状态,如果有效并且未访问,则将
      所有有效的相邻状态进行入队,并且设置这些状态为已访问,然后
    5. 跳到第2步重复执行检查最后出队的元素是否为最终解,如果是输出结果,否则说明无解

    通常用队列(先进先出,FIFO)实现

    初始化队列q;
    q = {起点u};标记s为已访问;
    while(q为非空){
        去q队首元素 now;now出队;
        If(now == 目标状态) {….}
        所有与now 相连 并 且未被访问的点进入队列(没被标记);
        并标记now已访问;
    }
    

    矩形宽搜:

    题目描述
    一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。(1<=m,n<=100)?
    输入输出格式
    输入格式:

    输入:整数m,n(m行,n列)
    矩阵
    输出格式:

    输出:细胞的个数
    /*
    4 10
    0 2 3 4 5 0 0 0 6 7
    1 0 3 4 5 6 0 5 0 0
    2 0 4 5 6 0 0 6 7 1
    0 0 0 0 0 0 0 0 8 9
    */

    #include<cstdio>
    #define maxn 100
    
    int m,n,cnt = 0;
    char s[maxn];
    int a[maxn][maxn],vis[maxn][maxn];
    
    int q[maxn];
    int movex[5] = {0,1,-1,0,0};
    int movey[5] = {0,0,0,1,-1};
    
    void bfs(int x, int y) {
        int l = 0, r = 0;
        q[r++] = x;
        q[r++] = y;//按顺序加入  取出时就是按的这个顺序取出
        while(l < r) {//当 l = r时 队列为空  就找完第53行传入的点附近的数(可以和它构成cells的) 
            int nowx = q[l++];
            int nowy = q[l++];//取出当前点的位置
            for(int i = 1; i <= 4; i++) {//判断四个方向(上下左右)的数  
                int ix = nowx + movex[i];//当前(四个之一)方向上的坐标
                int iy = nowy + movey[i];
                if(ix < 1 || iy < 1 || ix > n || iy > m) continue;//一定要写!!!矩阵的bfs的边界 
                //if(ix == 0 || iy == 0 || ix || ix > n || iy > m)  continue;//最好写上面的 
                if(a[ix][iy]) {
                    if(!vis[ix][iy]) {//再次判断它用不用被选 选过之后就没必要选了 
                        vis[ix][iy] = 1;
                        q[r++] = ix;
                        q[r++] = iy;//入队 
                    } 
                }
            }
        }
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= n; i++) {
            scanf("%s",s);//先输入一行较长的字符数组,因为原题的没有空格 
            for(int j = 1; j <= m; j++) {
                a[i][j] = s[j - 1] - '0';//s[j - 1]是s的第一个元素 
            }
        }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(!vis[i][j]) {//找出没有走过的点
                    vis[i][j] = 1;//做标记
                    if(a[i][j]) { //这才是找到可以宽搜的 点
                        bfs(i,j);
                        cnt++;
                    }
                }
            }
        }
        printf("%d",cnt);
    }
    
    

    DFS;

    通常搜出组合方式,求最优解的时候,我们考虑用DFS

    数据结构:系统栈;

  • 相关阅读:
    快速提取某一文件夹下所有文件名称
    CFileFind类的使用总结
    FILE文件流的中fopen、fread、fseek、fclose的使用
    经典损失函数:交叉熵(附tensorflow)
    tensorboard使用
    Windows下 tensorboard出现ValueError:Invalid format string
    新建全色或者resize(毫无价值,只是做记录)
    创建一个任意大小的全色矩阵 python
    转移图片位置
    getpatch
  • 原文地址:https://www.cnblogs.com/tyner/p/10972470.html
Copyright © 2011-2022 走看看