题意:

个格子组成的迷宫,迷宫中有陷阱 '#',和可通行的点 '.',起点为 'S',终点为 'T'。
每次移动代价为 1。
另有传送阵若干,可以从传送阵的入口传送至出口,代价为 3。
问从起点移动到终点的最小代价。

解法:

不考虑传送阵,最裸的 BFS。
考虑传送阵,也算是比较经典的模型。
有两种解法,但本质思想是一样。
一种是建图,迷宫中的每一个格子视作一个顶点,上下左右相邻的格子间建一条权值为 1 的双向边。
传送阵的入口和出口之间建一条权值为 3 的单向边。
然后跑个最短路 dijstra 就行了。
另一种是堆优化的 BFS,实现也和 dijkstra 很类似。只不过不用重新建图。
代码实现的就是这种方式。

Code:

#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
const int N = 300 + 5;
const int dx[] = {-1, 0, 0, 1}, dy[] = {0, -1, 1, 0};
 struct Node {
     int val, x, y;
     Node() { }
     Node(int _val, int _x, int _y): val(_val), x(_x), y(_y) { } 
     bool operator < (const Node &t) const {
         return val > t.val;
     }
 };
char maze[N][N];
int n, m, q;
vector<pii> a[N][N];
int sx, sy, ex, ey, step[N][N];
int main() {
    while(cin >> n >> m >> q) {
        for(int i = 1; i <= n; i++) 
            for(int j = 1; j <= m; j++) {
                cin >> maze[i][j];
                if(maze[i][j] == 'S') sx = i, sy = j;
                if(maze[i][j] == 'T') ex = i, ey = j;
                a[i][j].clear();
                step[i][j] = 0x3f3f3f3f;
            }
        for(int i = 1; i <= q; i++) {
            int x1, y1, x2, y2;
            cin >> x1 >> y1 >> x2 >> y2;
            x1++, y1++, x2++, y2++;
            a[x1][y1].push_back({x2, y2});
        }
        step[sx][sy] = 0;
        priority_queue<Node> q;
        q.push(Node(0, sx, sy));
        while(!q.empty()) {
            int val = q.top().val, x = q.top().x, y = q.top().y; q.pop();
            if(step[x][y] < val) continue;
            for(int i = 0; i < 4; i++) {
                int nx = x + dx[i], ny = y + dy[i];
                if(1 <= nx && nx <= n && 1 <= ny && ny <= m && maze[nx][ny] != '#' && step[nx][ny] > step[x][y] + 1) {
                    step[nx][ny] = step[x][y] + 1;
                    q.push(Node(step[nx][ny], nx, ny));
                }
            }
            for(pii e : a[x][y]) {
                int nx = e.first, ny = e.second;
                if(1 <= nx && nx <= n && 1 <= ny && ny <= m && maze[nx][ny] != '#' && step[nx][ny] > step[x][y] + 3) {
                    step[nx][ny] = step[x][y] + 3;
                    q.push(Node(step[nx][ny], nx, ny));
                }
            }
        }
        int ans = step[ex][ey];
        if(ans == 0x3f3f3f3f) ans = -1;
        cout << ans << endl;
    }
}