题意:
输出 Y 和 M 到 KFC 最短时间总和。
思路:
两次 BFS 时间相加,最小的那个即为答案。除了 '#' 不能走,其余的都可以走且每走一步就需要 11 minutes。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1e6+10;
int vis[1010][1010];
char a[1010][1010];
int d[1010][1010]; //到这点最少经过的路口数
int n,m,ans;
int b[4][2]={
-1,0,
1,0,
0,-1,
0,1
};
struct node
{
int x,y;
int step; //经过几个路口
};
void bfs(int x,int y,int flag)
{
memset(vis,0,sizeof(vis));
queue<node> q;
node w,h;
w.x = x;
w.y = y;
w.step = 0;
q.push(w);
vis[w.x][w.y] = 1;
while(!q.empty())
{
h = q.front();
q.pop();
for(int i=0;i<4;i++)
{
w.x = h.x+b[i][0];
w.y = h.y+b[i][1];
if(!vis[w.x][w.y] && a[w.x][w.y]!='#' && w.x>=0&&w.x<n && w.y>=0&&w.y<m)
{
w.step = h.step+1;
if(a[w.x][w.y]=='@' && flag==1) //第一次BFS 直接替换
d[w.x][w.y] = w.step;
else if(a[w.x][w.y]=='@' && flag==2) //第二次BFS 直接相加
{
d[w.x][w.y] += w.step;
ans = min(ans,d[w.x][w.y]);
}
vis[w.x][w.y] = 1;
q.push(w);
}
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
ans = inf;
memset(d,inf,sizeof(d));
for(int i=0;i<n;i++)
scanf("%s",a[i]);
int flag = 1; //判断第几次搜索
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(a[i][j]=='Y')
{
bfs(i,j,flag);
flag++;
}
else if(a[i][j]=='M')
{
bfs(i,j,flag);
flag++;
}
}
}
printf("%d\n",ans*11);
}
return 0;
}