题目链接:传送门Biubiubiu~~
分析:一开始是想不出来怎么在多个KFC中找到距离J和M最短的那个,看了别人题解才做出来。。。所谓双BFS其实就是BFS两次而已,从J开始BFS和从M开始BFS,然后用一个KFCstep[ 0/1][x] [y ]来记录到达所有KFC时需要走的步数,然后循环比较就好了~~
AC代码:
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
struct node{
int x,y,step;
};
int n,m;
const int INF=0x3f3f3f3f;
char maze[205][205];
bool vis[205][205];
int KFCstep[2][205][205]; //记录所有到达KFC点所需要的步数
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
bool check(int x,int y){
if(x>=0&&x<n&&y>=0&&y<m) return 1;
else return 0;
}
void bfs(int a,int x,int y){
memset(vis,false,sizeof(vis));
node point,newpoint;
point.x=x; point.y=y; point.step=0;
queue<node> que;
vis[x][y]=true;
que.push(point);
while(!que.empty()){
point=que.front();
que.pop();
if(maze[point.x][point.y]=='@'){
KFCstep[a][point.x][point.y]=point.step;
}
for(int i=0;i<4;i++){
newpoint.x=point.x+d[i][0];
newpoint.y=point.y+d[i][1];
newpoint.step=point.step+1;
if(check(newpoint.x,newpoint.y)&&!vis[newpoint.x][newpoint.y]&&maze[newpoint.x][newpoint.y]!='#'){
que.push(newpoint);
vis[newpoint.x][newpoint.y]=true;
}
}
}
}
int main(){
while(cin>>n>>m){
int Yx,Yy,Mx,My;
for(int i=0;i<n;i++){
cin>>maze[i];
for(int j=0;j<m;j++){
if(maze[i][j]=='Y'){
Yx=i; Yy=j;
}
if(maze[i][j]=='M'){
Mx=i; My=j;
}
}
}
memset(KFCstep,INF,sizeof(KFCstep));
bfs(0,Yx,Yy);
bfs(1,Mx,My);
int total=INF;
for(int i=0;i<n;i++){ //比较出走的最少步数的那个
for(int j=0;j<m;j++){
if(maze[i][j]=='@'){
total=min(total,(KFCstep[0][i][j]+KFCstep[1][i][j]));
}
}
}
cout<<total*11<<endl;
}
}