hdu 2612 Find a way

这题目,唉,一开始以为很简单的,就是枚举每一个KFC到M和Y的距离,求出最短的,结果TLE了

之后,突然想到了双向搜索,天呐,又郁闷了很久,从来都没写过,一时不只从何下手,而且,不知道搜索时的停止条件该如果设置,结果就……

回到一开始最不想做的,就是分别用调用俩次BFS,算出M和Y到每一个KFC的最短距离,再累加求最短即可

这时候要注意,BFS退出的条件是遍历完所有的点,所以遇到‘@’时,把相应时间累加之后,还是要继续搜

另外,有一点也是十分重要的 ,就是未必每一个KFC都是可达的,所以要多加一步判断………唉………

#include<iostream>
#include<string>
#include<queue>
using namespace std;
int n,m,dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
char map[201][201];
bool vis[201][201];
struct node
{
	int x,y,cnt;
}f[2000];
//f[]用来记录每一个KFC的坐标
node f1,f2;//记录M和Y 的坐标
int a[201][201];//累加到达每一个KFC的时间
queue<node> Q;
void bfs()
{
	while(!Q.empty())
	{
		node t=Q.front(),temp;
		Q.pop();
		if(map[t.x][t.y]=='@')
		{
			a[t.x][t.y]+=t.cnt;
		}
		for(int k=0;k<4;k++)
		{
			int i=t.x+dir[k][0];
			int j=t.y+dir[k][1];
			if(i>n||i<1||j>m||j<1||vis[i][j]||map[i][j]=='#') continue;
			vis[i][j]=1;
			temp.x=i;temp.y=j;temp.cnt=t.cnt+1;
			Q.push(temp);
		}
	}
	return ;
}
int main()
{
	int num;
	while(cin>>n>>m)
	{ 
		num=0;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
			{
				cin>>map[i][j];
				if(map[i][j]=='M')
				{
					f1.x=i;f1.y=j;
					f1.cnt=0;
				}
				if(map[i][j]=='Y')
				{
					f2.x=i;f2.y=j;
					f2.cnt=0;
				}
				if(map[i][j]=='@')
				{
					f[num].x=i;f[num].y=j;
					num++;
				}
			}
		memset(a,0,sizeof(a));//这部分代码有点乱,不够和谐,但还是很清晰的
		while(!Q.empty()) Q.pop();
		memset(vis,0,sizeof(vis));
		vis[f1.x][f1.y]=1;
		Q.push(f1);
		bfs( );
		memset(vis,0,sizeof(vis));
		while(!Q.empty()) Q.pop();
		vis[f2.x][f2.y]=1;
		Q.push(f2);
		bfs( );
		int max1=INT_MAX;
		for(int i=0;i<num;i++)
		{
			if(a[f[i].x][f[i].y]!=0&&a[f[i].x][f[i].y]<max1)//少了一个判断条件,多WA了几次
				max1=a[f[i].x][f[i].y];
		}
		cout<<max1*11<<endl;
	}
	return 0;
}
posted @ 2011-08-11 22:53  枕边梦  阅读(347)  评论(0编辑  收藏  举报