BFS思想与核心

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

  bfs算法是利用了queue(队列)来执行的,而队列先进先出的性质则是需要深刻体会的。例如:拓扑排序,图的bfs,树上的bfs,计算树的深度,计算树的直径等等(后续我的博客会更新相应的题目链接以及讲解)。所以在学习bfs之前,我强烈建议大家仔细体会下队列的用法。

    之前学习bfs算法求解迷宫问题或者最短路以及最短时间等问题时,脑海里都没有一张图,他的遍历过程都不是很熟悉,现在算是理解的比较清楚啦,总而言之,不管是树上还是图中运用bfs,都是可以将其遍历顺序画成一个树,且该树每个结点都只有一个唯一的父亲节点。

    来举个栗子:

                                           

          图a就是我们最常见的bfs最短路讲解图(每个小方格里面记录的是左上角起点距当前格子的最短距离);图b则是我们按照bfs的遍历顺序,将每个点标号。此时我们就会发现,这路径是一棵树。倘若还是看不出来,请看下图:

                               

    理解了这个之后,就会很好的帮助我们输出bfs的遍历顺序,当然到现在为止,我也水过一道dfs的遍历顺序输出题目(题目链接:http://codeforces.com/problemset/problem/1006/E),相对于bfs来说,dfs的输出以及遍历是比较好理解的。

    讲解结束,来,上基础题目:

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1548

                                             A strange lift

                          Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
                                               Total Submission(s): 32033    Accepted Submission(s): 11469

Problem Description

There is a strange lift.The lift can stop can at every floor as you want, and there is a number Ki(0 <= Ki <= N) on every floor.The lift have just two buttons: up and down.When you at floor i,if you press the button "UP" , you will go up Ki floor,i.e,you will go to the i+Ki th floor,as the same, if you press the button "DOWN" , you will go down Ki floor,i.e,you will go to the i-Ki th floor. Of course, the lift can't go up high than N,and can't go down lower than 1. For example, there is a buliding with 5 floors, and k1 = 3, k2 = 3,k3 = 1,k4 = 2, k5 = 5.Begining from the 1 st floor,you can press the button "UP", and you'll go up to the 4 th floor,and if you press the button "DOWN", the lift can't do it, because it can't go down to the -2 th floor,as you know ,the -2 th floor isn't exist.
Here comes the problem: when you are on floor A,and you want to go to floor B,how many times at least he has to press the button "UP" or "DOWN"?

 Input

The input consists of several test cases.,Each test case contains two lines.
The first line contains three integers N ,A,B(
1 <= N,A,B <= 200) which describe above,The second line consist N integers k1,k2,....kn.
A single 0 indicate the end of the input.

 Output

For each case of the input output a interger, the least times you have to press the button when you on floor A,and you want to go to floor B.If you can't reach floor B,printf "-1".

Sample Input

5 1 5

3 3 1 2 5

0

Sample Output

3

解题思路:

      题意:一共有n层,每层都给你一个相应的可跳转值,每次读入起始楼层和目标楼层,请问最少操作几次可以到达目标楼层?

     数据范围:1 --- 200    分析:数据不是很大,因此可以执行多次bfs。(有时候遇到多组以及数据较大时,可以将bfs提前先执行,做好预处理工作)

     思路:位于初始楼层的人,有三种选择方向:站在原地(时刻都不要忘记,有些题目样例会在这卡),向上,向下。因此,我从初始楼层开始向三个方向bfs遍历,当遇到目标楼层返回即可。

Tip(小贴士):

     所有题目中看似复杂的问题,都是由现实生活中抽象来的,这也是为了让我们发散思维去解决现实问题,因此当自己想不通的时候,将问题带入自己的身边,带入现实生活中,也许就会很快获得答案。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;

int n,a,b;
int dir[205];
int step[205];    //因为题目中楼层和步数的关系可以用一维数组来表示,因此我就没有用结构体来存储.
bool vis[205];
int mo[] = {1,0,-1};      //三个方向

void BFS()
{
	bool flag = 1;        //反证法:假设不能够到达目标楼层.
	queue<int>que;
	que.push(a);
	step[a] = 0;
	vis[a] = 1;
	while(!que.empty())
	{
		a = que.front();
		que.pop();
		if(a == b)        //不知道你们在刚开始学习bfs的时候有没有疑惑:为什么要将目标楼层的判断语句写在这里?  (现在你懂了吗?)如果你懂了,恭喜你!你成功学会了bfs.
		{
			flag = 0;         //此处找到目标楼层,更新flag.
			printf("%d\n",step[b]);
		}
		for(int i = 0;i <= 2; i++)
		{
			int t = a + mo[i] * dir[a];
//			printf("%d %d^^^^%d^^^%d\n",a,t,mo[i],vis[t]);
			if(t >= 1 && t <= n && !vis[t])
			{
				vis[t] = 1;
				step[t] = step[a] + 1;
		//		printf("%d***\n",step[t]);
				que.push(t);
			}
		}
	}
	if(flag)               //当队列里面所有点都不能到达时,再输出-1.
		printf("-1\n");
}



int main()
{
	while(~scanf("%d %d %d",&n,&a,&b) && n)
	{
		memset(vis,0,sizeof(vis));
		memset(step,-1,sizeof(step));
		for(int i = 1;i <= n; i++)
			scanf("%d",&dir[i]);
		BFS();
	}
	return 0;
}

                                              Welcome to my blog, and I hope what I write will help you.

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值