打表预处理会降低复杂度,如果每次找一个'@'都跑一次bfs的话会超时;
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const double epos=1e-8;
const int maxn=209;
int n,m;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
char a[maxn][maxn];//图;
int flag[maxn][maxn];
struct Node{
int x,y;
}s1,s2,dnode;//s1表示Y位置,s2表示M位置,dnode表示移动后的位置;
int check(int i,int j){
if(i>=0&&i<n&&j>=0&&j<m&&flag[i][j]==0&&(a[i][j]=='.'||a[i][j]=='@'))
return 1;
return 0;
}
int step[maxn][maxn][2];//预处理打表记录Y,M到每个点的距离;
queue<Node>q;
void bfs(Node st,int fff){
memset(flag,0,sizeof(flag));
while(!q.empty())
q.pop();
flag[st.x][st.y]=1;
q.push(st);
while(!q.empty()){
Node tan1=q.front();
q.pop();
for(int i=0;i<4;i++){
dnode.x=tan1.x+dx[i];
dnode.y=tan1.y+dy[i];
if(check(dnode.x,dnode.y)){
flag[dnode.x][dnode.y]=1;
step[dnode.x][dnode.y][fff]=step[tan1.x][tan1.y][fff]+1;
q.push(dnode);
}
}
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
memset(step,0,sizeof(step));
for(int i=0;i<n;i++)
scanf("%s",a[i]);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
if(a[i][j]=='Y'){
s1.x=i,s1.y=j;
bfs(s1,0);
}
if(a[i][j]=='M'){
s2.x=i,s2.y=j;
bfs(s2,1);
}
}
//若两点之间没有路,不可达,一开始初始化是0,
//由于需要求最小的值,所以需要将没有路的改为无穷大
for(int h=0;h<2;h++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(step[i][j][h]==0)
step[i][j][h]=inf;
int minn=inf;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(a[i][j]=='@')
minn=min(minn,step[i][j][0]+step[i][j][1]);
printf("%d\n",minn*11);
}
return 0;
}