hdoj 1242 不同步的bfs

以前曾经做过每一步都是平等的bfs 今天的这一题让我开阔了视野

因为上一步和下一步所花费的时间可能不同

下一步的来源可以分为两种情况 1 来自时间短的 2 来自时间长的

因此我们必须有一个选择的过程 这就需要一个记忆化数组 用来保存当前格的最少时间

犯了memset 的错误 memset 是一个字节一个字节初始化的 显然不对

其他的都和hero in maze 一样 是一个很老实的广搜

从这里我认为 其实是广搜被扩展了 。。。

好题 赞一个!

#include <iostream>
#include <string.h>
#include <queue>
using namespace std;
typedef struct Node
{
   int x;
   int y;
   int step;
}Node;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
bool visited[202][202];
int dp[202][202];      //记忆化dp数组的建立
char map[202][202];
int m,n;
bool inmap(int x,int y)
{
  return x>=0&&x<m&&y>=0&&y<n;
}
int min(int x,int y)
{
  if(x<y)return x;
  else return y;
}
int minstep=0x7fffffff;
void  bfs(int x,int y)
{
 //
 queue<Node>q;
 Node p;
 p.x=x;
 p.y=y;
 p.step=0;//初始化
 q.push(p);
 
 while(!q.empty())
 {
	 p=q.front();
	 q.pop();
	 int i;
	 for(i=0;i<4;i++)
	 {
		 Node temp;
		 temp.x=p.x+dx[i];
		 temp.y=p.y+dy[i];
         if(map[temp.x][temp.y]!='#' && inmap(temp.x,temp.y))///        并非像visited那么简单 这里需要的是一种记忆化搜索 或者说这里其实是使用了一种动态规划 因为上一次搜到的状态与下一次相关
		 {
            if(p.step+1<dp[temp.x][temp.y])
			{
				dp[temp.x][temp.y]=p.step+1;
				temp.step=p.step+1;
				if(map[temp.x][temp.y]=='x')
					temp.step++;
			//	cout<<"dddddd"<<endl;
				if(map[temp.x][temp.y]=='r')
				   	minstep=min(temp.step,minstep);///注意到因为朋友会有不止一个 可以先找出朋友的个数 但是这也可能是访问到的同一个朋友  所以需要的是访问到朋友的最小步数
		//		cout<<temp.x<<" "<<temp.y<<endl;
				q.push(temp);
			}
		 }
	 }
 }

}
int main()
{
    while(cin>>m>>n)
	{
		int i,j,c,d;
		for(i=0;i<m;i++)
			for(j=0;j<n;j++)
			{
			   cin>>map[i][j];
			   if(map[i][j]=='a')
			   {
				   c=i;
				   d=j;

			   }
			  dp[i][j]=0x7fffffff;
			}
		//	cout<<c<<" "<<d<<endl;

		bfs(c,d);
		if(minstep!=0x7fffffff)
		  cout<<minstep<<endl;
		else
			cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;
		minstep=0x7fffffff;
	}
	return 0;
}


 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值