样例输入
8 10
P.####.#P#
…#…#…#
…#T##.#.#
…
…##.#####
…
#####…##
###…S##
样例输出
21
思路
用两次bfs,第一次计算出起点到P的距离,第二次计算出T到P的距离,然后循环取最小值。
但是WA了很多次,找了很久,发现是vis判断的问题,导致一个数据更新多次。
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef pair<int ,int > P;
int n,m;
char g[2005][2005];
int res[2][2005][2005];
bool vis[2][2005][2005];
int dx[]={0,-1,0,1};
int dy[]={1,0,-1,0};
bool check(int x,int y){
if(x<0||y<0||x>=n||y>=m||g[x][y]=='#')return false;
return true;
}
void bfs(int x,int y,int k){
queue<P> qe;
qe.push(P(x,y));
res[k][x][y]=0;
vis[k][x][y]=true;
while(!qe.empty()){
//cout << qe.size() << endl;
int x=qe.front().first;
int y=qe.front().second;
qe.pop();
for(int i=0;i<4;i++){
int ex=x+dx[i];
int ey=y+dy[i];
if(check(ex,ey)){
if(vis[k][ex][ey])continue;
vis[k][ex][ey]=true;
res[k][ex][ey]=res[k][x][y]+1;
//cout << ex << " " << ey <<" " << res[k][ex][ey] << endl;
qe.push(P(ex,ey));
}
}
}
}
int main(){
cin >> n >> m;
for(int i=0;i<n;i++){
cin >> g[i];
}
int sx,sy,tx,ty;
queue<P> qe;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(g[i][j]=='P'){
qe.push(P(i,j));
}
else if(g[i][j]=='S'){
sx=i;
sy=j;
}
else if(g[i][j]=='T'){
tx=i;
ty=j;
}
}
}
memset(res,0x3f,sizeof(res));
bfs(sx,sy,0);
//cout <<res[0][3][3] << endl;
bfs(tx,ty,1);
int ans=0x4fffff;
while(!qe.empty()){
int x=qe.front().first;
int y=qe.front().second;
qe.pop();
ans=min(res[0][x][y]+res[1][x][y],ans);
}
cout << ans << endl;
return 0;
}
/*
10 10
P.####.#P#
..#..#...#
..#T##.#.#
...PPP....
..##P#####
....PPPP..
.####PPP##
.##....S##
........##
##########
*/