BFS:HDU2612-Find a way(双向BFS)
Find a way
Time Limit: 3000/1000 MS (Java/Others) Memory
Limit: 32768/32768 K (Java/Others)
Total Submission(s): 403 Accepted Submission(s): 129
Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city. So yifenfei made arrangements with Merceki to meet at a KFC. There are many KFC in Ningbo, they want to choose one that let the total time to it be most smallest.
Now give you a Ningbo map, Both yifenfei and Merceki can move up, down ,left, right to the adjacent road by cost 11 minutes.
Each test case include, first two integers n, m. (2<=n,m<=200).
Next n lines, each line included m character.
‘Y’ express yifenfei initial position.
‘M’ express Merceki initial position.
‘#’ forbid road;
‘.’ Road.
‘@’ KCF
Y.#@
....
.#..
@..M
4 4
Y.#@
....
.#..
@#.M
5 5
Y..@.
.#...
.#...
@..M.
#...#
66
88
66
解题心得:
1、关于双向bfs的判定,一般是有两个移动的点,没有目标或者一个目标,当有三个或者更多的移动的点的时候一般要考虑是否可以用一些技巧消去一些。
2、双向bfs在找最小的路径之和的时候并不是找到了之后马上跳出,因为并不是第一个相遇的点一定是最短的点,所以在不超时,数据量比较小的时候尽量跑完,不然很可能在某个角落差生错误,找都找不到,在跑双向bfs 的时候标记一定要弄好,不然很目标是一个bfs跑了两次,这就很恼火了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 210;
char maps[maxn][maxn];
int y_x,y_y,m_x,m_y;
int dir[4][2] ={0,1,0,-1,1,0,-1,0};
int n,m,Min,num_2;
bool use[2][maxn][maxn];//两个bfs,标记也要开两层
struct Vis
{
int num;//记录这个@点被找到了几次
bool is;
int sum;//用来记录两个bfs在@点相遇的时间的和
} vis[maxn][maxn];
struct node
{
int x,y;
};
queue<node>q[2],qt;//两个bfs的队列和层使用的队列 bool check(int x,int y)//检查一下可不可以走到那里
{
if(x<0 || y<0 || x>=n || y>=m)
return true;
if(maps[x][y] == '#')
return true;
return false;
}
void pre_maps()
{
//初始化很重要
Min = 0x7f7f7f7f;
memset(use,0,sizeof(use));
num_2 = 0;
while(!q[0].empty())
q[0].pop();
while(!q[1].empty())
q[1].pop();
while(!qt.empty())
qt.pop(); for(int i=0; i<n; i++)
scanf("%s",maps[i]);
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
vis[i][j].is = false;
vis[i][j].num = 0;
vis[i][j].sum = 0;
if(maps[i][j] == 'Y')
{
y_x = i;
y_y = j;
use[0][y_x][y_y] = true;
}
if(maps[i][j] == 'M')
{
m_x = i;
m_y = j;
use[1][m_x][m_y] = true;
}
if(maps[i][j] == '@')//将@记录一下,在后面直接判断就行了
{
vis[i][j].is = true;
}
}
} bool bfs(int num,int ans)
{
node now,Next;
qt = q[num];
while(!qt.empty())
{
now = qt.front();
qt.pop();
q[num].pop();
for(int i=0; i<4; i++)
{
Next.x = now.x + dir[i][0];
Next.y = now.y + dir[i][1];
if(check(Next.x,Next.y)) continue;
if(vis[Next.x][Next.y].is && !use[num][Next.x][Next.y])
{
if(vis[Next.x][Next.y].num == 1)//被两个bfs找到,并且是两个不同的bfs,一定要做好标记啊,不然很恼火的,是两个不同的bfs
{
vis[Next.x][Next.y].sum += ans;//两次的时间和
Min = min(Min,vis[Next.x][Next.y].sum);//记录两个不同的bfs到达@的时间和的最小的那个
}
else if(vis[Next.x][Next.y].num == 0)//被一个bfs被找到
{
vis[Next.x][Next.y].sum += ans;
vis[Next.x][Next.y].num ++;
}
}
if(!use[num][Next.x][Next.y])
{
use[num][Next.x][Next.y] = true;
q[num].push(Next);
}
}
}
}
int get_ans()
{
int ans = 0;
node now;
now.x = y_x;
now.y = y_y;
q[0].push(now);
now.x = m_x;
now.y = m_y;
q[1].push(now); bool flag1 = false;
bool flag2 = false;
while(!q[0].empty() || !q[1].empty())//两个bfs一层一层的跑
{
ans += 11;//每走一步花11分钟
bfs(0,ans);
bfs(1,ans);
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
pre_maps();
get_ans();
printf("%d\n",Min);
}
return 0;
}
BFS:HDU2612-Find a way(双向BFS)的更多相关文章
- UVA1601-The Morning after Halloween(双向BFS)
Problem UVA1601-The Morning after Halloween Accept: 289 Submit: 3136 Time Limit: 12000 mSec Problem ...
- HDU 1242 -Rescue (双向BFS)&&( BFS+优先队列)
题目链接:Rescue 进度落下的太多了,哎╮(╯▽╰)╭,渣渣我总是埋怨进度比别人慢...为什么不试着改变一下捏.... 開始以为是水题,想敲一下练手的,后来发现并非一个简单的搜索题,BFS做肯定出 ...
- 洛谷 P1379 八数码难题(map && 双向bfs)
题目传送门 解题思路: 一道bfs,本题最难的一点就是如何储存已经被访问过的状态,如果直接开一个bool数组,空间肯定会炸,所以我们要用另一个数据结构存,STL大法好,用map来存,直接AC. AC代 ...
- POJ1915Knight Moves(单向BFS + 双向BFS)
题目链接 单向bfs就是水题 #include <iostream> #include <cstring> #include <cstdio> #include & ...
- HDU 3085 Nightmare II 双向bfs 难度:2
http://acm.hdu.edu.cn/showproblem.php?pid=3085 出的很好的双向bfs,卡时间,普通的bfs会超时 题意方面: 1. 可停留 2. ghost无视墙壁 3. ...
- POJ 3170 Knights of Ni (暴力,双向BFS)
题意:一个人要从2先走到4再走到3,计算最少路径. 析:其实这个题很水的,就是要注意,在没有到4之前是不能经过3的,一点要注意.其他的就比较简单了,就是一个双向BFS,先从2搜到4,再从3到搜到4, ...
- [转] 搜索之双向BFS
转自:http://www.cppblog.com/Yuan/archive/2011/02/23/140553.aspx 如果目标也已知的话,用双向BFS能很大程度上提高速度. 单向时,是 b^le ...
- 双向BFS
转自“Yuan” 如果目标也已知的话,用双向BFS能很大提高速度 单向时,是 b^len的扩展. 双向的话,2*b^(len/2) 快了很多,特别是分支因子b较大时 至于实现上,网上有些做法是用两个 ...
- HDU 3085 Nightmare Ⅱ (双向BFS)
Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 3085 Nightmare Ⅱ 双向BFS
题意:很好理解,然后注意几点,男的可以一秒走三步,也就是三步以内的都可以,鬼可以穿墙,但是人不可以,鬼是一次走两步 分析:我刚开始男女,鬼BFS三遍,然后最后处理答案,严重超时,然后上网看题解,发现是 ...
随机推荐
- hibernate课程 初探单表映射1-2 ORM定义
1 什么是ORM? ORM(Object / RelationShip Mapping) 对象/关系映射 面向对象编程(OOP)最终要把对象信息保存在关系性数据库中,要写好多sql语句.这与面向对象编 ...
- 使用Python开发环境Wing IDE设立项目注意事项
使用Wing IDE的第一步是建立一个项目文件,这样Wing IDE就可以找到并分析源代码,存储工作. Wing IDE会自动以默认的项目进行启动.在本教程中用户也可以使用这个默认项目进行示例操作.如 ...
- 用C#来控制高级安全Windows防火墙
有的时候我们需要在自己的产品中检测<高级安全Windows防火墙>的状态,并有可能需要加入一些规则甚至需要关闭掉高级安全Windows防火墙. 下面就告诉如何来做: <高级安全Win ...
- Cocos2d-x v3.1 安装图文教程(二)
Cocos2d-x v3.1 安装图文教程(二) 如果我们需要在Android平台上运行就必须安装android的SDK,如果我们只想在window上运行就只需要安装Cocos2d-x就行了.当 ...
- linux 命令——18 locate (转)
locate 让使用者可以很快速的搜寻档案系统内是否有指定的档案.其方法是先建立一个包括系统内所有档案名称及路径的数据库,之后当寻找时就只需查询这个数据库,而不必实际深入档案系统之中了.在一般的 di ...
- NOIP2018提高组Day2 解题报告
前言 关于\(NOIP2018\),详见此博客:NOIP2018学军中学游记(11.09~11.11). \(Day2\)的题目和\(Day1\)比起来,真的是难了很多啊. \(T1\):旅行(点此看 ...
- js实现指定日期增加指定月份
首先,大致思路为: 1. 先将字符串格式的时间类型转化为Date类型 2. 再将Date类型的时间增加指定月份 3. 最后将Date类型的时间在转化为字符串类型 1. 先将字符串格式的时间类型转化为 ...
- hadoop install
1.home下建立hadoop 2.在Downloads下解压hadoop-2.6.0.tar.gz 3.将解压后的hadoop-2.6.0移动到/home/hadoop 4.csf@ubuntu:/ ...
- tomcat服务器用Servlet类查找磁盘文件上的Json信息,如果匹配则在浏览器上显示出该条内容的全部信息
package com.swift; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOE ...
- iOS多播Delegate类——GCDMulticastDelegate用法小结
iOS中通常的delegate模式只能有一个被委托的对象,这样当需要有多个被委托的对象时,实现起来就略为麻烦,在开源库XMPPFramework中提供了一个GCDMulticastDelegate类, ...