您的位置:首页 > 其它

bfs题目小结

2016-03-26 22:57 344 查看
转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents          
by---cxlove

刚好yobobobo最近做BFS,我也被渲染了,当是复习一下,也总结一下吧,大部分是HDOJ上的BFS题目,由于本人时间有限,会持续更新

HDU 1548 http://acm.hdu.edu.cn/showproblem.php?pid=1548

基础的BFS,每次有两个方向,分别把步数乘以1和-1就行了。其余的都是基础BFS,注意下起点终点重合的情况

HDU 1372http://acm.hdu.edu.cn/showproblem.php?pid=1372

经典的马步移动,基本的BFS改成8个方向,同样处理即可

HDU 2717 http://acm.hdu.edu.cn/showproblem.php?pid=2717

3种情况移动,+1,-1,*2,没啥好说的,同样处理就行了,同时注意下边界,比目标大的话就只能全部-1,如果比目标大了就没必要*2

HDU 3766 http://acm.hdu.edu.cn/showproblem.php?pid=3766

比较坑,开始以为和1372一样,其实不是,这题没有给出范围,但是范围很大,之前需要逼近下,然后再搜索,或者直接枚举判断下就行了

HDU 1026 http://acm.hdu.edu.cn/showproblem.php?pid=1026

其实做法一样,需要打怪耗时,需要用优先队列或者最小堆来处理下,不过这题比较纠结的是需要输出路径,首先注意细节问题,之前用的是next,保存后继结点,果断被坑,一个点在搜索的时候的后继结点会有好多,果断改成pre,前趋表示。

HDU 1072 http://acm.hdu.edu.cn/showproblem.php?pid=1072

题目总体思路很明确,遇到数字4的话,时间重置下,在判重的时候需要用三维数组,加一个当前时间,如果两次到某点剩余时间相同,那就没必要再走了。

HDU 1175 http://acm.hdu.edu.cn/showproblem.php?pid=1175

弱爆了,果断也被坑了,开始觉得只要保存某个结点的方向和已拐的弯,然后搜索就行了,其实只要沿某条直线先一直搜到底就行了,不过还是要保存方向和已拐的弯的个数。

HDU 1180 http://acm.hdu.edu.cn/showproblem.php?pid=1180

注意下楼梯部分的细节问题就行了,可以停在原地等待楼梯转向,这里比较坑啊,而且楼梯处不需要标记,可能两个方向都要走

HDU 1242 http://acm.hdu.edu.cn/showproblem.php?pid=1242

果断BFS+优先队列

HDU 1728 http://acm.hdu.edu.cn/showproblem.php?pid=1728

类似于连连看,限制了拐弯次数,只需要每个方向走到底就行了,题目输入有些坑,行列有点混乱应注意。而且如果之前搜过的点,之后不能停止而是跳过。

HDU 2579 http://acm.hdu.edu.cn/showproblem.php?pid=2579

由于 在K的倍数的时候石头会消失,所以不能像其它迷宫问题一样判重,可能当前时间石头还在,而走一圈再回来石头消失,也许就有其它的路径可以走,因此判断的时候要加上三维数组flag[x][y][time%k],如果到某点的时间取余都相同,那么此时的状态就是完全相同,没有意义的

 

HDU 2012 http://acm.hdu.edu.cn/showproblem.php?pid=2102

三维的BFS,注意一些细节就行了,譬如进入传送门就必须传送,而且另一边必须只有是空地才行,坑死了,读题不仔细

 

HDU 1253 http://acm.hdu.edu.cn/showproblem.php?pid=1253

三维BFS,木有问题,注意优化下

 

HDU 1240 http://acm.hdu.edu.cn/showproblem.php?pid=1240

三维BFS水之

HDU 1429 http://acm.hdu.edu.cn/showproblem.php?pid=1429

BFS+二进制压缩存储,很明显要保存你拿过的钥匙的状态,总共10把钥匙,使用二进制压缩才1024个状态,开始还打算把门的状态也保存下来,结果莫名其秒的TLE,后来发现只需要钥匙的状态,因为钥匙可以用很多次,但是又莫名其妙的MLE,好吧,不解释,彻底晕了flag[x][y][key],表示在(x,y)手上钥匙状态为key

HDU 1254 http://acm.hdu.edu.cn/showproblem.php?pid=1254

经典的推箱子游戏,注意判重需要一个三维数组,可用两次B FS解决,或者BFS+DFS

详情请移步   http://blog.csdn.net/acm_cxlove/article/details/7639306

HDU 2612 http://acm.hdu.edu.cn/showproblem.php?pid=2612

两个人到同一点的和最短,分别以两个人为起点,遍历整个图,计算出到每个KFC的最短距离,然后枚举所有的KFC,算最小的代价

HDU 1983 http://acm.hdu.edu.cn/showproblem.php?pid=1983

最差的情况直接把出口或者入口四个方向封住,所以最多只要堵4次。BFS找出最短的路径,并保存路径,DFS处理路径上的点,BFS判断是否连通。

HDU 1195 http://acm.hdu.edu.cn/showproblem.php?pid=1195

题目不难,1W个可能,判重很简单,就是转化有点纠结,至少我写得很矬

HDU 2128 http://acm.hdu.edu.cn/showproblem.php?pid=2128

坑爹的题目,不过题目很好,BFS和DFS都可以做

具体请见http://blog.csdn.net/acm_cxlove/article/details/7635497

贴代码:

HDU 1240 三维BFS

/*
02. ID:cxlove
03. */
04. #include<iostream>
05. #include<cstdio>
06. #include<cstring>
07. #include<queue>
08. #define LL unsigned long long
09. using namespace std;
10. int n,m,q;
11. int way[6][3]={{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};
12. char str[15][15][15];
13. bool flag[15][15][15];
14. struct Node{
15. int x,y,z,step;
16. bool check(){
17. if(x>=0&&y>=0&&z>=0&&x<n&&y<n&&z<n)
18. return true;
19. return false;
20. }
21. }s,e,u,v;
22. int bfs(){
23. if(s.x==e.x&&s.y==e.y&&s.z==e.z)
24. return 0;
25. queue<Node>que;
26. memset(flag,false,sizeof(flag));
27. s.step=0;
28. que.push(s);
29. flag[s.x][s.y][s.z]=true;
30. while(!que.empty()){
31. u=que.front();
32. que.pop();
33. for(int i=0;i<6;i++){
34. v=u;
35. v.x+=way[i][0];
36. v.y+=way[i][1];
37. v.z+=way[i][2];
38. v.step++;
39. if(v.check()&&flag[v.x][v.y][v.z]==false){
40. flag[v.x][v.y][v.z]=true;
41. if(v.x==e.x&&v.y==e.y&&v.z==e.z)
42. return v.step;
43. if(str[v.x][v.y][v.z]=='X')
44. continue;
45. que.push(v);
46. }
47. }
48. }
49. return -1;
50. }
51. char ch[100];
52. int main(){
53. while(scanf("%s%d",ch,&n)!=EOF){
54. for(int i=0;i<n;i++)
55. for(int j=0;j<n;j++)
56. scanf("%s",str[i][j]);
57. while(scanf("%s",ch)){
58. if(strcmp(ch,"END")==0)
59. break;
60. sscanf(ch,"%d",&s.x);
61. scanf("%d%d%d%d%d",&s.y,&s.z,&e.x,&e.y,&e.z);
62. int ans=bfs();
63. if(ans==-1)
64. printf("NO ROUTE\n");
65. else
66. printf("%d %d\n",n,ans);
67. }
68.
69. }
70. return 0;
71. }

HDU 1728 限制拐弯次数

#include<iostream>
02. #include<cstdio>
03. #include<cstring>
04. #include<queue>
05. #define LL unsigned long long
06. using namespace std;
07. int n,m,k;
08. int way[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
09. char str[105][105];
10. bool flag[105][105];
11. struct Node{
12. int x,y,dir,cnt;
13. bool check(){
14. if(x>=0&&x<n&&y>=0&&y<m)
15. return true;
16. return false;
17. }
18. }s,e,u,v;
19. int bfs(){
20. queue<Node>que;
21. que.push(s);
22. memset(flag,false,sizeof(flag));
23. flag[s.x][s.y]=true;
24. while(!que.empty()){
25. u=que.front();
26. que.pop();
27. for(int i=0;i<4;i++){
28. v.cnt=u.cnt;
29. if(u.dir!=-1&&u.dir!=i)
30. v.cnt++;
31. if(v.cnt>k)
32. continue;
33. v.dir=i;
34. for(int j=1;;j++){
35. v.x=u.x+way[i][0]*j;
36. v.y=u.y+way[i][1]*j;
37. if(v.check()&&str[v.x][v.y]!='*'){
38. if(flag[v.x][v.y])
39. continue;
40. flag[v.x][v.y]=true;
41. if(v.x==e.x&&v.y==e.y)
42. return true;
43. que.push(v);
44. }
45. else
46. break;
47. }
48. }
49. }
50. return false;
51. }
52. int main(){
53. int t;
54. scanf("%d",&t);
55. while(t--){
56. scanf("%d%d",&n,&m);
57. for(int i=0;i<n;i++)
58. scanf("%s",str[i]);
59. scanf("%d%d%d%d%d",&k,&s.y,&s.x,&e.y,&e.x);
60. s.x--;s.y--;e.x--;e.y--;
61. s.cnt=0;s.dir=-1;
62. if((s.x==e.x&&s.y==e.y)||bfs())
63. printf("yes\n");
64. else
65. printf("no\n");
66. }
67. return 0;
68. }

HDU 1242 BFS+优先队列

#include<cstdio>
02. #include<cstring>
03. #include<iostream>
04. #include<algorithm>
05. #include<queue>
06. #define LL long long
07. using namespace std;
08. struct Node{
09. int x,y,step;
10. bool operator<(const Node &n1)const{
11. return step>n1.step;
12. }
13. }s,e,u,v;
14. int n,m;
15. char str[205][205];
16. int way[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
17. int bfs(){
18. priority_queue<Node>que;
19. bool flag[205][205];
20. memset(flag,0,sizeof(flag));
21. s.step=0;
22. que.push(s);
23. flag[s.x][s.y]=1;
24. while(!que.empty()){
25. u=que.top();
26. que.pop();
27. for(int i=0;i<4;i++){
28. v.x=u.x+way[i][0];
29. v.y=u.y+way[i][1];
30. if(v.x>=0&&v.y>=0&&v.x<n&&v.y<m&&flag[v.x][v.y]==0&&str[v.x][v.y]!='#'){
31. flag[v.x][v.y]=1;
32. if(str[v.x][v.y]=='x')
33. v.step=u.step+2;
34. else
35. v.step=u.step+1;
36. if(v.x==e.x&&v.y==e.y)
37. return v.step;
38. que.push(v);
39. }
40. }
41. }
42. return -1;
43. }
44. int main(){
45. while(scanf("%d%d",&n,&m)!=EOF){
46. for(int i=0;i<n;i++){
47. scanf("%s",str[i]);
48. for(int j=0;j<m;j++)
49. if(str[i][j]=='a'){
50. s.x=i;
51. s.y=j;
52. }
53. else if(str[i][j]=='r'){
54. e.x=i;
55. e.y=j;
56. }
57. }
58. int ans=bfs();
59. if(ans==-1)
60. printf("Poor ANGEL has to stay in the prison all his life.\n");
61. else
62. printf("%d\n",ans);
63. }
64. return 0;
65. }


HDU 1429 BFS+二进制压缩

#include<iostream>
02. #include<cstdio>
03. #include<cstring>
04. #include<queue>
05. #include<vector>
06. #define LL unsigned long long
07. using namespace std;
08. int n,m,T;
09. int way[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
10. char str[21][21];
11. bool flag[21][21][1024];
12. struct Node{
13. short x,y,step;
14. short key;
15. bool check(){
16. if(x>=0&&x<n&&y>=0&&y<m)
17. return true;
18. return false;
19. }
20. }s,e,u,v;
21. queue<Node>que;
22. int bfs(){
23. if(!que.empty())
24. que.pop();
25. que.push(s);
26. memset(flag,false,sizeof(flag));
27. while(!que.empty()){
28. u=que.front();
29. que.pop();
30.
31. for(int i=0;i<4;i++){
32. v=u;
33. v.step++;
34. v.x+=way[i][0];
35. v.y+=way[i][1];
36.
37. if(v.step>=T)
38. break;
39. if(v.check()&&str[v.x][v.y]!='*'){
40. if(str[v.x][v.y]=='^')
41. return v.step;
42. if(str[v.x][v.y]>='A'&&str[v.x][v.y]<='J'){
43. if(((1<<(str[v.x][v.y]-'A'))&v.key)&&flag[v.x][v.y][v.key]==false){
44. que.push(v);
45. flag[v.x][v.y][v.key]=true;
46. }
47. }
48. else if(str[v.x][v.y]>='a'&&str[v.x][v.y]<='j'){
49. v.key|=(1<<(str[v.x][v.y]-'a'));
50. if(flag[v.x][v.y][v.key]==false){
51. que.push(v);
52. flag[v.x][v.y][v.key]=true;
53. }
54. }
55. else{ //相当于空地
56. if(!flag[v.x][v.y][v.key]){
57. flag[v.x][v.y][v.key]=true;
58. que.push(v);
59. }
60. }
61. }
62.
63. }
64. }
65. return -1;
66. }
67. int main(){
68. while(scanf("%d%d%d",&n,&m,&T)!=EOF){
69. for(int i=0;i<n;i++){
70. scanf("%s",str[i]);
71. for(int j=0;j<m;j++){
72. if(str[i][j]=='@'){
73. s.x=i;
74. s.y=j;
75. s.step=0;
76. s.key=0;
77. }
78. }
79. }
80. printf("%d\n",bfs());
81. }
82. return 0;
83. }
原文链接:http://blog.csdn.net/alalalalalqp/article/details/9155457
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bfs