Description

Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki. 

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. 

 

Input

The input contains multiple test cases. 

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 

 

Output

For each test case output the minimum total time that both yifenfei and Merceki to arrival one of KFC.You may sure there is always have a KFC that can let them meet.

 

Sample Input

 4 4

Y.#@

....

.#..

@..M

4 4

Y.#@

....

.#..

@#.M

5 5

Y..@.

.#...

.#...

@..M.

#...#

        

 

Sample Output

66

88

66

分析:双向就是利用两个BFS拼在一起,一个从起点开始搜索,一个从终点开始搜索

当两个BFS搜索的轨迹有重合的部分的时候,立即停止两个BFS,并根据当前重合点的与两个BFS已得到的信息来计算答案。

求2个点到KFC的距离之和,使其最小,可用2次BFS,

分别求出2个点到各个KFC的最短距离,

然后找出和最小的即可

利用队列来做BFS

#include<queue>
#include<stdio.h>
#include<string.h>
using namespace std;
int dx[4]={1,0,-1,0};//设定SS的4个方向
int dy[4]={0,1,0,-1};
int n,m;
int vis[210][210],dist[210][210],distY[210][210],a[210][210];
void bfs(int x,int y){
	queue<int> q;
	int u=x*m+y;
	q.push(u);
	vis[x][y]=1;//表示设置的区域没有被访问过
	dist[x][y]=0;
	while(!q.empty()){
		u.front();//在一边排好队的最前面
		q.pop();//入队
		x=u/m;y=u%m;
		for(int i=0;i<4;i++){
			int nx=x+dx[i],ny=y+dy[i];//探头
			//如果找到目标,并且没有被访问过
			if(nx>=0&&ny>=0&&nx<n&&ny<n&&!vis[nx][ny]&&a[nx][ny]==0){
			//重新设置新的方向,不会往上s
			u=nx*m+ny;
			vis[nx][ny]=1;
			dist[nx][ny]=dist[x][y]+1;//往下加一层
			q.push(u);//新的值入队,直到不满足条件

			}
		}
	}

}
int main(){
	int i,j,Yx,Yy,Mx,My;
	char s[210][210];
	while(scanf("%d%d",&n,&m)!=EOF){
		memset(a,0,sizeof(a));
		memset(vis,0,sizeof(vis));
		memset(dist,0,sizeof(dist));
		memset(distY,0,sizeof(distY);
		for(i=0;i<n;i++){
			scanf("%s",&s[i]);
			for(j=0;j<m;j++){
				if(s[i][j]=='#') a[i][j]=1;  //表示不能走
                if(s[i][j]=='Y') {Yx=i,Yy=j;}  //表示Y的起始位置
                if(s[i][j]=='M') {Mx=i,My=j;}//表示M的起始位置

			}
		}
		bfs(Yx,Yy);//让Y开始向下BFS
		printf("%d %d\n",Yx,Yy);
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(s[i][j]=='@')//如果到达目的地,
				distY[i][j]=dist[i][j];//就把这个坐标点的位置赋给Y,它的功能就完成了,就坐等M了
			}
			printf("%d\n",distY[i][j]);//打印
			//开始让Mss
			memset(a,0,sizeof(a));
		    memset(vis,0,sizeof(vis));
			memset(dist,0,sizeof(dist));'
			for(i=0;i<n;i++)
				for(j=0;j<m;j++)
					if(s[i][j]=='#')
					a[i][j]=1;//表示不能走
			bfs(Mx,My);//M开始向上BFS
			int min=1000000;
			for(i=0;i<n;i++)
				for(j=0;j<m;j++)
				//这个条件相当重要,此题能不能AC就取决于它,计算走过的最小值
				if(s[i][j]=='@'&&dist[i][j]+distY[i][j]<min&&dist[i][j]&&distY[i][j]){
					min=dist[i][j]+distY[i][j];
				}
			printf("%d\n",min*11);

		}
	}
}

利用数组来做,其实原理都差不多

#include <stdio.h>
#include <cstring>
#define Max 0x7f7f7f7f
using namespace std;
int visited1[205][205];
int visited2[205][205];
int ans1[205][205];
int ans2[205][205];
int x1,y1,x2,y2;
int n,m;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
char map[205][205];
struct node
{
    int x;
    int y;
};
node path[80000];
void bfs(int x ,int y,int ans[205][205],int visited[205][205])
{
    memset(visited,0,sizeof(visited));
    memset(ans,Max,sizeof(ans));
    path[0].x=x;
    path[0].y=y;
    ans[x][y]=0;
    int head=0;
    int tail=1;
    visited[x][y]=1;
    while(head<tail)
    {
        x=path[head].x;
        y=path[head].y;
        for(int i=0;i<4;i++)
        {
            int xx=x+dir[i][0];
            int yy=y+dir[i][1];
            if(visited[xx][yy]==0 && xx>=0 && xx<n && yy>=0 && yy<m && map[xx][yy]!='#')
            {
                path[tail].x=xx;
                path[tail].y=yy;
                tail++;
                ans[xx][yy]=ans[x][y]+1;
                visited[xx][yy]=1;
            }
        }
        head++;
    }
}
int main()
{
    char ch;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        getchar();
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%c",&ch);
                map[i][j]=ch;
                if(ch=='Y')
                {
                    x1=i;
                    y1=j;
                }
                if(ch=='M')
                {
                    x2=i;
                    y2=j;
                }
            }
            getchar();
        }
        memset(visited1,0,sizeof(visited1));
        memset(ans1,Max,sizeof(ans1));
        bfs(x1,y1,ans1,visited1);
        memset(visited2,0,sizeof(visited2));
        memset(ans2,Max,sizeof(ans2));
        bfs(x2,y2,ans2,visited2);
        int min=Max;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(map[i][j]=='@'&& ans1[i][j]!=Max && ans2[i][j]!=Max)
                {
                    if(min>ans1[i][j]+ans2[i][j])
                    min=ans1[i][j]+ans2[i][j];
                }
            }
        }
        printf("%d\n",min*11);
    }

    return 0;
}

HDU2612---(两次BFS)的更多相关文章

  1. UVa 11624,两次BFS

    题目链接:http://vjudge.net/contest/132239#problem/A 题目链接:https://uva.onlinejudge.org/external/116/11624. ...

  2. POJ 1475 Pushing Boxes 搜索- 两重BFS

    题目地址: http://poj.org/problem?id=1475 两重BFS就行了,第一重是搜索箱子,第二重搜索人能不能到达推箱子的地方. AC代码: #include <iostrea ...

  3. UVa 1599 Ideal Path (两次BFS)

    题意:给出n个点,m条边的无向图,每条边有一种颜色,求从结点1到结点n颜色字典序最小的最短路径. 析:首先这是一个最短路径问题,应该是BFS,因为要保证是路径最短,还要考虑字典序,感觉挺麻烦的,并不好 ...

  4. UVA 11624 Fire!(两次BFS+记录最小着火时间)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  5. CSU - 2031 Barareh on Fire (两层bfs)

    传送门: http://acm.csu.edu.cn/csuoj/problemset/problem?pid=2031 Description The Barareh village is on f ...

  6. hihocoder#1050 : 树中的最长路(树中最长路算法 两次BFS找根节点求最长+BFS标记路径长度+bfs不容易超时,用dfs做TLE了)

    #1050 : 树中的最长路 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中, ...

  7. Fire! UVA - 11624 (两步bfs)

    题目链接 题意 人要从迷宫走出去,火会向四个方向同时扩散 分析 两步bfs,先出火到达各地时的时间(设初始时间为0,人每走一步为1s,在着一步内火可以向四周可触及的方向同时扩散),然后在bfs人,人能 ...

  8. Find a way(两个BFS)

    Problem Description Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. L ...

  9. 求树的直径【两遍BFS】

    两遍BFS.从任意一个点出发,第一遍可以找到直径的一端,从这端出发即可找到另外一端. 证明:从U点出发,到达V[画个图便清晰了] 1.如果U在直径上,则V一定是直径的一个端点. 2.如果U不在直径上. ...

随机推荐

  1. Python 线程池,进程池,协程,和其他

    本节内容 线程池 进程池 协程 try异常处理 IO多路复用 线程的继承调用 1.线程池 线程池帮助你来管理线程,不再需要每个任务都创建一个线程进行处理任务. 任务需要执行时,会从线程池申请线程,有则 ...

  2. day4 liaoxuefeng--调试、线程、正则表达式

    一.错误.调试和测试 二.进程和线程 三.正则表达式

  3. C语言第二次作业——顺序结构

    一.改错题 1.输出带框文字:在屏幕上输出以下3行信息. (1)源程序 对程序进行编译,发现错误信息1 错误原因:stdio拼写错误 改正方法:将stdio正确拼写 对程序进行编译,发现错误信息2 错 ...

  4. Mysql--执行计划 Explain

    0 介绍 0.1 是什么 使用 Explain 关键字可以模拟优化器执行 Sql 查询语句,从而知道 Mysql 是如何处理 Sql 的. 0.2 用法 Explain + Sql语句 0.3 执行计 ...

  5. 正则替换replace中$1的用法以及常用正则

    一.repalce定义 用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串. stringObject.replace(regexp/substr,replacement)参数一 ...

  6. linux上安装fastdfs+nginx+ngin-module实践并解决多个异常篇

    为什么选择Nginx Nginx 是一个很牛的高性能Web和反向代理服务器, 它具有有很多非常优越的特性: 在高连接并发的情况下,Nginx是Apache服务器不错的替代品:Nginx在美国是做虚拟主 ...

  7. Docker学习系列(三)Docker搭建gitlab的两种方式

    一.直接下载docker-ce 1.拉取gitlab/gitlab-ce Randy:~ Randy$ docker pull gitlab/gitlab-ce Using default tag: ...

  8. rhel7 启动网络

    我装的是rhel7 服务器版本(在virtualbox虚拟机里),安装后默认不启动网络,另外还有很多命令也不能用,比如ifconfig, yum-config-manager等. 先解决网络问题: 切 ...

  9. Oracle中的列转行例子详解

    数据如下:name id张三 1,2,3 要求实现:name id张三 1张三 2张三 3 --创建临时表 create table tmp as(select '张三' name, '1,2,3' ...

  10. python笔记二(数据类型和变量、编码方式、字符串的编码、字符串的格式化)

    一.数据类型 python可以直接处理的数据类型有:整数.浮点数.字符串.布尔值.空值. 整数 浮点数 字符串:双引号内嵌套单引号,可以输出 i'm ok. 也可以用\来实现,\n 换行 \t tab ...