这是一篇学习题解(别人的bfs简洁明了 我的一坨糊
1、字符串处理 提前记录起点终点 用结构体数组记录传送坐标并且使用完初始化
2、提前用数组模拟行走 这样每次用循环即可省略一部分代码
3、用数组记录当前地点当前的最低步数 好比较并且确保正确
4、要重复使用的都做到了每次都有初始化(确保正确

#include<bits/stdc++.h>
#define ll long long
#define N 405
using namespace std;
const int dx[5]={1,-1,0,0},dy[5]={0,0,1,-1};
int n,m,f[N][N],ex,ey,sx,sy,q,u1[N*3],v1[N*3];
char ch;
char a[N][N];
struct he{
    int u,v,t;
}b[N][N];
queue<he>Q;
void bfs(int sx,int sy){
    int ans=10000000;
    while(!Q.empty()) Q.pop();
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) f[i][j]=10000000;///记录步数
    f[sx][sy]=0;///起点
    Q.push((he){sx,sy,0});
    while(!Q.empty()){
        he p=Q.front();Q.pop();
        if(p.u==ex&&p.v==ey) {
            ans=min(ans,p.t);
            continue;
        }
        if(b[p.u][p.v].u!=-1){///是否要传送
            int x1=b[p.u][p.v].u;
            int y1=b[p.u][p.v].v;
            if(a[x1][y1]!='#'&&f[x1][y1]>p.t+3){
                f[x1][y1]=p.t+3;
                Q.push((he){x1,y1,p.t+3});
            }
        }
        for(int i=0;i<4;i++){
            int x1=p.u+dx[i];
            int y1=p.v+dy[i];
            if(x1<n&&x1>=0&&y1>=0&&y1<m&&a[x1][y1]!='#'&&f[x1][y1]>p.t+1){
                f[x1][y1]=p.t+1;
                Q.push((he){x1,y1,p.t+1});
            }
        }
    }
    if(ans!= 10000000)
    printf("%d\n",ans);else printf("-1\n");
}
int main(){
    for(int i=0;i<=300;i++)
        for(int j=0;j<=300;j++) b[i][j].u=b[i][j].v=-1;
    while(scanf("%d%d%d",&n,&m,&q)!=EOF){
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++){
                scanf("%c",&ch);
                while(ch!='.'&&ch!='S'&&ch!='T'&&ch!='#') ch=getchar();
                a[i][j]=ch;
                if(ch=='S') sx=i,sy=j;///起点
                if(ch=='T') ex=i,ey=j;///终点
            }
        for(int i=1;i<=q;i++){
            scanf("%d%d",&u1[i],&v1[i]);///传送起点
            scanf("%d%d",&b[u1[i]][v1[i]].u,&b[u1[i]][v1[i]].v);
        }
        bfs(sx,sy);
        for(int i=1;i<=q;i++)
            b[u1[i]][v1[i]].u=-1,b[u1[i]][v1[i]].v=-1;
    }
}