题意:在一个n x m个格子组成的迷宫,'#'表示的格子不能走,'.'表示可以走。起点用'S'表示,目的地用'T'表示。只能向上下左右相邻的格子移动,每移动一次花费1秒。有q个单向传送阵,每个传送阵各有一个入口和一个出口,在入口处,你可以选择是否传送,传送过程会花费3秒;
注意:一个格子可能既有多个入口,又有多个出口。
请求出到达目的地的最短时间?

思路:用优先队列写bfs

代码:

#include<bits/stdc++.h>
#define ll long long

using namespace std;

int n, m, q, dx[4]={1,-1,0,0}, dy[4]={0,0,1,-1};

char s[505][505];

vector<int> g[100005];//记录传送阵,用一个整数表示位置,整数=x*300+y;

struct state
{
    int x, y;
}st,en;

struct w
{
    int x, y, t;
}w, w1;

bool operator<(struct w a,struct w b)
{
    return a.t>b.t;
};

int f[305][305];

int bfs()
{
    memset(f,-1,sizeof(f));
    priority_queue<struct w> que;
    w.x=st.x;
    w.y=st.y;
    w.t=0;
    que.push(w);
    while(!que.empty())
    {
        w=que.top();
        que.pop();
        if(f[w.x][w.y]!=-1)
        {
            continue;
        }
        printf("%d %d %d\n",w.x,w.y,w.t);
        f[w.x][w.y]=w.t;
        if(w.x==en.x&&w.y==en.y)
        {
            return f[w.x][w.y];
        }
        for(int i=0;i<4;i++)
        {
            w1.x=w.x+dx[i];
            w1.y=w.y+dy[i];
            w1.t=w.t+1;
            if(w1.x>=0&&w1.x<n&&w1.y>=0&&w1.y<m&&f[w1.x][w1.y]==-1&&s[w1.x][w1.y]!='#')
            {
                que.push(w1);
            }
        }
        int v=w.x*300+w.y;
        for(int i=0;i<g[v].size();i++)
        {
            w1.x=g[v][i]/300;
            w1.y=g[v][i]%300;
            w1.t=w.t+3;
            if(w1.x>=0&&w1.x<n&&w1.y>=0&&w1.y<m&&f[w1.x][w1.y]==-1&&s[w1.x][w1.y]!='#')
            {
                que.push(w1);
            }
        }
    }
    return -1;
}

int main()
{
    while(~scanf("%d%d%d",&n,&m,&q))
    {
        for(int i=0;i<n;i++)
        {
            scanf("%s",s[i]);
        }
        for(int i=0;i<q;i++)
        {
            int x, y, x2, y2;
            scanf("%d%d%d%d",&x,&y,&x2,&y2);
            g[x*300+y].push_back(x2*300+y2);
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(s[i][j]=='S')
                {
                    st.x=i;
                    st.y=j;
                }
                if(s[i][j]=='T')
                {
                    en.x=i;
                    en.y=j;
                }
            }
        }
        int z=bfs();
        printf("%d\n",z);
        for(int i=0;i<100005;i++)
        {
            g[i].clear();
        }
    }
    return 0;
}