广度优先搜索(BFS)
面临类似于查找最短路径的问题时候,可以尝试使用图来建立模型,再使用广度优先搜索来解决问题。
广度优先搜索可以回答两类问题:
第一类问题:从节点A出发,有前往节点B的路径吗?
第二类问题:从节点A出发,前往节点B的哪条路径最短?
假设你经营着一个芒果农场,需要寻找芒果销售商,以便将芒果卖给他,为此,你可以在朋友中查找芒果供应商。
首先,你需要创建一个朋友名单:
ALICE | |
BOB | |
CLAIRE |
依次检查是否是芒果供应商,如果刚好有朋友是芒果供应商,这就是最优选择,假设你没有朋友死芒果供应商,那么你必须在朋友的朋友中查找,因此,如果ALICE不是芒果供应商,就将其朋友也加入名单中,用队列(queue)来实现。
我们来看一个广度优先搜索的例题:
马的遍历
题目描述
有一个 n \times mn×m 的棋盘,在某个点 (x, y)(x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。
输入格式
输入只有一行四个整数,分别为 n, m, x, yn,m,x,y。
输出格式
一个 n \times mn×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 -1−1)。
输入输出样例
输入 #1复制
3 3 1 1输出 #1复制
0 3 2 3 -1 1 2 1 4说明/提示
数据规模与约定
对于全部的测试点,保证 1 \leq x \leq n \leq 4001≤x≤n≤400,1 \leq y \leq m \leq 4001≤y≤m≤400。
#include<stdio.h>
int head=0,tail=0;
int n,m,x,y;
struct node
{
int r;
int c;
};
struct node t[100000]={0};
int vis[1000][1000]={0};
int dx[8]={-2,-2,2,2,1,-1,1,-1}; //可以走的x轴位置数
int dy[8]={-1,1,-1,1,2,-2,-2,2}; //可以走的y轴的位置数
int main()
{
scanf("%d%d%d%d",&n,&m,&x,&y);
int i,j,tx,ty;
t[head].r=x; //将马的初始位置入队
t[head].c=y;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
vis[i][j]=-1; 将初始位置赋值为-1,如果有没有走到的位置,值就为-1
vis[x][y]=0; //马的起始位置赋值0
tail++;
while(head<tail)
{
for(i=0;i<8;i++)
{
tx=t[head].r+dx[i]; //马走的方向
ty=t[head].c+dy[i];
if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&vis[tx][ty]==-1)
{
t[tail].r=tx;
t[tail].c=ty;
//入列
vis[tx][ty]=vis[t[head].r][t[head].c]+1;
//马走日,下一个走到的坐标的步数是前一个的和+1
tail++;
}
}
head++;
//出队
}
//输出最后的结果步数
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
printf("%-5d",vis[i][j]);
printf("\n");
}
return 0;
}