HDU 2612 N - Find a way // 两次bfs 做题要条理清晰

HDU 2612 N - Find a way

Problem 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

题意:

经过一年的学习,在杭州,Y飞终于抵达宁波故乡。 离宁波一年,Y有很多人见面。 特别是M好朋友。
Y的家位于乡村,但M的家位于市中心。 因此,Y与M安排在KFC会面。 宁波有很多KFC,他们想选择一个让总时间最小的KFC。
现在给你一张宁波地图,Y和M都可以花11分钟向上,向下,向左,向右移动到相邻的道路。 

最初我的思路是写两个bfs,一个是Y的bfs,一个是M的bfs,但是我发现,每一次找出的都是最优的路径然后就退出了,假如Y和M最优的KFC不是同一个地点,那么虽然是最优的路径,但也是错误的;

后来,我就觉得用bfs只能找出最优的路径,不能找出所有的KFC路径,我就又用了dfs,当我把代码敲到dfs函数的时候,我就想到,我用dfs找到的所有的KFC路径就不是最优的路径了,所以我又把dfs否定了;

然后我就想着,还是要用bfs,这样才能找到KFC最优的路径,但是困扰我的问题是我不能把所有的KFC的最优的路径找到,只能找到一个最优的KFC路径;

这一晚上我都在思考这一个问题:从我做题的思路中,我对自己要提出几点要求:首先做题目的时候,要想清楚用什么样的算法,题目写到一半,不断改正浪费时间,后期再换写法更是浪费时间,而且换的思路也不正确尴尬;其次,深入思考,花费的时间多一些没关系,但是要把题目和做题过程理解清楚,要条理清晰;最后,独立思考,题目要练扎实。

我的收获:让我对bfs又过了更深的理解,同时对队列也更加熟悉使用,更加熟悉了算法的过程,条理清晰了很多,对以后的做题很有帮助

今晚上把这个题目做出来了,实话说这个题目并不难,只是我一开始条理不太清晰,才会各种方法的去乱尝试,还是题目做的不多,不够熟练的原因。

我的做题思路:  用一个数组来标记走过的路径,用vis来标记我走过的点,用了两次bfs,每一次bfs完成之后,我就把路径给复制下来,然后清零继续再走M的路径,走完之后,再把路径复制下来,这样Y和M的路径我都有了,剩下的就是找出两个人在最少的时间内到达同一个KFC。

AC代码

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stdlib.h>
#include<math.h>
using namespace std;
struct node
{
	int x;
	int y;
}last,now;
queue<node>Q;
char mp[300][300];
int vis[300][300];
int step[300][300],step1[300][300],step2[300][300];
int dir[4][2]={0,1,1,0,0,-1,-1,0};
int n,m;
void bfs(int a,int b)
{
	while(!Q.empty())
       Q.pop();
    last.x=a;
    last.y=b;
    Q.push(last);
    while(!Q.empty())
    {
    	last=Q.front();
    	Q.pop();
      for(int i=0;i<4;i++)
      {
    	 now.x=last.x+dir[i][0];
		 now.y=last.y+dir[i][1];
		 if(now.x>=0&&now.x<=n&&now.y>=0&&now.y<=m&&mp[now.x][now.y]!='#'&&vis[now.x][now.y]==0)
		 {
		 	    Q.push(now);
		       vis[now.x][now.y]=1;
			   step[now.x][now.y]=step[last.x][last.y]+1;	
		 } 
	  }
	}

}
int main()
{
	int c,d,e,f;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		getchar();
		for(int i=0;i<n;i++)
		{
		  for(int j=0;j<m;j++)
		  {
		  	scanf("%c",&mp[i][j]);
		  	if(mp[i][j]=='Y')
		  	{
		  	    c=i;
			   	d=j;
			}
			if(mp[i][j]=='M')
			{
				e=i;
				f=j;
			}
		  }
		  getchar();
		}
		memset(vis,0,sizeof(vis));
		memset(step,0,sizeof(step));
		memset(step1,0,sizeof(step1));
		bfs(c,d);
		for(int i=0;i<n;i++)
	    {
	     for(int j=0;j<m;j++)
		 {
		     step1[i][j]=step[i][j]; 	
		 }	
		}	
		memset(vis,0,sizeof(vis));
		memset(step,0,sizeof(step));
		memset(step2,0,sizeof(step2));
		bfs(e,f);
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
		    {
		    	step2[i][j]=step[i][j];
			}
		}
		memset(vis,0,sizeof(vis));
		memset(step,0,sizeof(step));
		int minn=10000000;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				step[i][j]=step1[i][j]+step2[i][j];
				if(mp[i][j]=='@' && minn>step[i][j])
				{
					minn=step[i][j];
				}
			}
		}
		printf("%d\n",minn*11);
	}
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值