刚刚讲了bfs,那下面我们就来搞一个bfs的应用
同样先复习bfs模板。
Description
农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N,牛位于点K。
农夫有两种移动方式:
- 从XXX移动到X−1或X+1,每次移动花费一分钟。
- 从XXX移动到2∗X,每次移动花费一分钟。
假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花多少时间才能抓住牛?
Input
第一行为两个整数,分别为N和K。
Output
一个整数,农夫抓到牛所要花费的最小分钟数。
Sample Input 1
5 17Sample Output 1
4
宽度优先遍历
queue<int> q;
st[1] = true; // 表示1号点已经被遍历过
q.push(1);while (q.size())
{
int t = q.front();
q.pop();for (int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
if (!s[j])
{
st[j] = true; // 表示点j已经被遍历过
q.push(j);
}
}
}
这道题目相当于是一个以2的指数级不断扩展的满二叉树,逐渐枚举出所有情况,直到有一次情况满足即可。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 200010;
int st[N], n, k;
int q[N];
void bfs()
{
memset(st, -1, sizeof st);
int hh = 0, tt = -1;
q[++ tt] = n;
st[n] = 0;
while(hh <= tt)
{
int u = q[hh ++];
if(u == k) return;
if(u * 2 <= k * 2 && st[u * 2] == -1)
q[++ tt] = u * 2, st[u * 2] = st[u] + 1;
if(u + 1 <= k * 2 && st[u + 1] == -1)
q[++ tt] = u + 1, st[u + 1] = st[u] + 1;
if(u - 1 >= 0 && st[u - 1] == -1)
q[++ tt] = u - 1, st[u - 1] = st[u] + 1;
}
}
int main()
{
scanf("%d%d", &n, &k);
bfs();
printf("%d", st[k]);
return 0;
}
st记录距离
q记录层数
欢迎提问~