广度优先搜索(bfs)

文章介绍了两种遍历算法,一种是从一个初始点开始,逐步扩展到相邻节点并标记已访问过的节点;另一种是从多个绿色起点同时开始,计算每个点到这些起点的最近距离。算法使用队列结构存储节点,并利用邻接矩阵记录步数和访问状态。
摘要由CSDN通过智能技术生成

先访问完当前顶点的所有邻接点,然后再访问下一层的所有节点

例如

他的顺序应为

一层一层的走,先是1号点,然后是与1号点直接相邻的所有节点,再然后是直接与第2层相邻的点,以此类推。

代码和详解如下

#include<stdio.h>

struct ma {
    int x; // 横坐标
    int y; // 纵坐标
    int s; // 步数
};

int a[405][405]; // 用于输入,容纳矩阵
int book[405][405] = { 0 }; // 用于检查是否走过

int main() {
    struct ma queue[160000];
    int head; // 队首
    int tail; // 队尾

    int n, m, p, q;
    int tx, ty;

  
    scanf("%d %d %d %d", &n, &m,&p,&q);
    for(int g=0;g<=n;g++)
    {
        for(int l=0;l<=m;l++)
        {
            a[g][l]=-1;
        }
     } 
    head = 1;
    tail = 1;
    queue[tail].x = p;
    queue[tail].y = q;
    queue[tail].s = 0; // 将起始位置的步数设为0
    tail++;
    book[p][q] = 1;
    a[p][q]=0;
    int next[8][2] = { {-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1},{-2,-1},{-2,1} }; // 马的八个行走方向

    while (head < tail) // 队列的循环
    {
        for (int i = 0; i < 8; i++) {    
            tx = queue[head].x + next[i][0];
            ty = queue[head].y + next[i][1];
            if (tx > n || tx < 1 || ty > m || ty < 1) // 下一步可以行走的范围
            {
                continue;
            }
            if (book[tx][ty] == 0) // 重复经历的不走
            {
                queue[tail].s = queue[head].s + 1; // 将下一步节点的步数设置为当前节点的步数加1
                a[tx][ty] = queue[tail].s; // 将步数存入相对应的格子中
                queue[tail].x = tx; // 将新节点插入数据中
                queue[tail].y = ty;
                tail++;
                book[tx][ty] = 1;
            }
        }
        head++;
    }

    for (int j = 1; j <= n; j++) {
        for (int k = 1; k <= m; k++) {
            printf("%-5d", a[j][k]); // 输出结果
        }
        printf("\n");
    }

    return 0;
}

手结冰了只能这样了(这些图)

代码如下

#include<stdio.h>
struct tu{
    int x;//横坐标 
    int y;//纵坐标 
    
};
int main()
{
    struct tu f[1000];//队列 
    int a[35][35];//存储输入的数组 
    int book[35][35]={0};//用于标记 
    int n;
    scanf("%d",&n);
    int head;
    int tail;
    head=1;
    tail=1;
    f[tail].x =0;
    f[tail].y =0;
    tail++;
    for(int i=0;i<=n+1;i++)
    {
        for(int j=0;j<=n+1;j++)
        {
            a[i][j]=0;
        }
    }//将原本的数组进行拓展,这可以使得外层可能间断的0连续便于搜索 
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }//输入数组 
    int next[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//上下左右四个方向 
    book[0][0]=1;
    int tx;//横坐标的下一步 
    int ty;//纵坐标的下一步 
    while(head<tail)
    {
        for(int k=0;k<4;k++)
        {
            tx=f[head].x +next[k][0];
            ty=f[head].y +next[k][1];
            if(tx<0||tx>n+1||ty<0||ty>n+1)
            {
                continue;
            }
            if(book[tx][ty]==0&&a[tx][ty]!=1)//条件是该点坐标不等于1且不重复 
            {book[tx][ty]=1;
                f[tail].x =tx;
                f[tail].y =ty;
                a[tx][ty]=3;//这个也比较重要,这个起着将搜索到的0标记之后再判断如果是3就输出0; 
                tail++;
                //将新数据弄进队列 
            }
        }
        head++;
    }
    for(int k=1;k<=n;k++)
    {
        for(int j=1;j<=n;j++)
        {
            if(a[k][j]==3){printf("0 ");
            }
             if(a[k][j]==1)//是1就输出1 
            {
                printf("1 ");
            }
            if(a[k][j]==0)//如果是0就输出2,外面的0经过搜索全部已经被标记成3了 
            {
                printf("2 ");
            }
            
        }printf("\n"); 
    }
}

还有一个

之前第一层都是一个初始点现在有多个把这些初始的点(绿色的那些点)全部送进队列里一起作为第一层开始搜索,从这些绿色的点开始蔓延,蔓延过的上标记,这样矩阵中的每一个点到绿点的距离都是最近的。

#include <stdio.h>

struct w {
    int x;
    int y;
    int s;
};

int book[501][501];
int a[501][501];

int main() {
    struct w f[250005];
    int n, m, p, q;
    int head, tail;
    head = 1;
    tail = 1;

    scanf("%d %d %d %d", &n, &m, &p, &q);
    for (int i = 1; i <= p; i++) {
        int o, r;
        scanf("%d %d", &o, &r);
        f[tail].x = o;
        f[tail].y = r;
        f[tail].s = 0;
        a[o][r] = 0;
        book[o][r] = 1;
        tail++;
    }//把这些初始点全部送进队列后面都是收悉的配方 

    int next[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    while (head < tail) {
        for (int j = 0; j < 4; j++) {
            int tx = f[head].x + next[j][0];
            int ty = f[head].y + next[j][1];
            if (tx < 1 || tx > n || ty < 1 || ty > m) {
                continue;
            }
            if (book[tx][ty] == 0) {
                book[tx][ty] = 1;
                f[tail].x = tx;
                f[tail].y = ty;
                f[tail].s = f[head].s + 1;
                a[tx][ty] = f[tail].s;
                tail++;
            }
        }
        head++;
    }
int e[2501];
int l=0;
    for (int s = 1; s <= q; s++) {
        int g, h;
        scanf("%d %d", &g, &h);
        e[l]=a[g][h];
        l++;
    }
    for(int z=0;z<l;z++)
    {
        printf("%d\n",e[z]);
    }

    return 0;
}

明天计划:

 写题单

  • 31
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值