https://vjudge.net/contest/425322#problem/I
题意概括
一个图上,标定两个人的初始位置和所有肯德基的位置,两个人在任意一个肯德基相遇时步数之和的最小值
细节
WA*n以后,才知道自己有多傻。。。
在分别以两个人的位置为出发点广搜时,要记录到任意一个肯德基的距离。但不是所有肯德基都能到达。所以这个时候就要有一些小技巧了。
注意下面的memset。
代码
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
char s[205][205];
int n,m,sx,sy,ex,ey;
int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}},ans[2][205][205],vis[205][205];///ans三维
struct node
{
int x,y,step;
};
void bfs(int flag)
{
queue<node>q;
node now;
if(flag==0) now.x=sx,now.y=sy;
else now.x=ex,now.y=ey;
now.step=0;
vis[now.x][now.y]=1;
q.push(now);
while(!q.empty())
{
now=q.front();
q.pop();
if(s[now.x][now.y]=='@')
{
ans[flag][now.x][now.y]=now.step;
}
int j;
for(j=0;j<4;j++)
{
int nx=now.x+dir[j][0],ny=now.y+dir[j][1];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&!vis[nx][ny]&&s[nx][ny]!='#')
{
vis[nx][ny]=1;
node next;
next.x=nx,next.y=ny,next.step=now.step+1;
q.push(next);
}
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
cin>>s[i][j];
if(s[i][j]=='Y') sx=i,sy=j;
if(s[i][j]=='M') ex=i,ey=j;
}
}
memset(ans,0x3f3f3f3f,sizeof(ans));
///初始时,把所有的距离都设置为0x3f3f3f3f,表示不能到达某个KFC
memset(vis,0,sizeof(vis));
bfs(0);
memset(vis,0,sizeof(vis));
bfs(1);
int mini=0x3f3f3f3f;///这个mini的初值也必须是0x3f3f3f3f
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(s[i][j]=='@')
{
mini=min(mini,ans[0][i][j]+ans[1][i][j]);///如果ans里面有一个数字是0x3f3f3f3f,取min的最终结果就必然是0x3f3f3f3f
}
}
}
printf("%d\n",11*mini);
}
return 0;
}