题意
传送门 NC 15665
题解
BFS
考虑到使用传送阵与向相邻格子移动花费的时间不同,用 两个队列 分别维护使用传送阵与向相邻格子移动的情况,每次按照广度递增出队,更新最短时间。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
#define maxn 305
struct P
{
int x, y;
};
struct node
{
int x, y, d;
};
int dx[4] = {0, 0, -1, 1}, dy[4] = {-1, 1, 0, 0};
int N, M, Q, sx, sy, tx, ty, dis[maxn][maxn];
char mat[maxn][maxn];
vector<P> door[maxn][maxn];
int main()
{
while (~scanf("%d%d%d", &N, &M, &Q))
{
for (int i = 0; i < N; ++i)
{
scanf(" %s", mat + i);
for (int j = 0; j < M; ++j)
{
door[i][j].clear();
if (mat[i][j] == 'S')
sx = i, sy = j;
if (mat[i][j] == 'T')
tx = i, ty = j;
}
}
for (int i = 0; i < Q; ++i)
{
int x, y, z, w;
scanf("%d%d%d%d", &x, &y, &z, &w);
door[x][y].push_back(P{z, w});
}
queue<node> q1, q2;
memset(dis, -1, sizeof(dis));
q1.push(node{sx, sy, 0});
dis[sx][sy] = 0;
while (dis[tx][ty] == -1 && (!q1.empty() || !q2.empty()))
{
int d = q1.empty() ? q2.front().d : q1.front().d;
while (!q1.empty() && q1.front().d == d)
{
node t = q1.front();
q1.pop();
for (int i = 0; i < 4; ++i)
{
int nx = t.x + dx[i], ny = t.y + dy[i];
if (nx >= 0 && nx < N && ny >= 0 && ny < M && dis[nx][ny] == -1 && mat[nx][ny] != '#')
{
dis[nx][ny] = d + 1;
q1.push(node{nx, ny, d + 1});
}
}
for (int i = 0; i < (int)door[t.x][t.y].size(); ++i)
{
P &p = door[t.x][t.y][i];
if (dis[p.x][p.y] == -1 && mat[p.x][p.y] != '#')
{
q2.push(node{p.x, p.y, d + 3});
}
}
}
while (!q2.empty() && q2.front().d == d)
{
node t = q2.front();
q2.pop();
dis[t.x][t.y] = t.d;
for (int i = 0; i < 4; ++i)
{
int nx = t.x + dx[i], ny = t.y + dy[i];
if (nx >= 0 && nx < N && ny >= 0 && ny < M && dis[nx][ny] == -1 && mat[nx][ny] != '#')
{
dis[nx][ny] = d + 1;
q1.push(node{nx, ny, d + 1});
}
}
for (int i = 0; i < (int)door[t.x][t.y].size(); ++i)
{
P &p = door[t.x][t.y][i];
if (dis[p.x][p.y] == -1 && mat[p.x][p.y] != '#')
{
q2.push(node{p.x, p.y, d + 3});
}
}
}
}
printf("%d\n", dis[tx][ty]);
}
return 0;
}
BFS + 优先队列
使用优先队列以广度顺序出队即可。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
#define maxn 305
struct P
{
int x, y;
};
struct node
{
int x, y, d;
bool operator<(const node &b) const
{
return d > b.d;
}
};
int dx[4] = {0, 0, -1, 1}, dy[4] = {-1, 1, 0, 0};
int N, M, Q, sx, sy, tx, ty, dis[maxn][maxn];
char mat[maxn][maxn];
vector<P> door[maxn][maxn];
int main()
{
while (~scanf("%d%d%d", &N, &M, &Q))
{
for (int i = 0; i < N; ++i)
{
scanf(" %s", mat + i);
for (int j = 0; j < M; ++j)
{
door[i][j].clear();
if (mat[i][j] == 'S')
sx = i, sy = j;
if (mat[i][j] == 'T')
tx = i, ty = j;
}
}
for (int i = 0; i < Q; ++i)
{
int x, y, z, w;
scanf("%d%d%d%d", &x, &y, &z, &w);
door[x][y].push_back(P{z, w});
}
priority_queue<node> q;
memset(dis, -1, sizeof(dis));
q.push(node{sx, sy, 0});
while (!q.empty())
{
node t = q.top();
q.pop();
dis[t.x][t.y] = t.d;
if (t.x == tx && t.y == ty)
break;
for (int i = 0; i < 4; ++i)
{
int nx = t.x + dx[i], ny = t.y + dy[i];
if (nx >= 0 && nx < N && ny >= 0 && ny < M && dis[nx][ny] == -1 && mat[nx][ny] != '#')
{
dis[nx][ny] = t.d + 1;
q.push(node{nx, ny, t.d + 1});
}
}
for (int i = 0; i < (int)door[t.x][t.y].size(); ++i)
{
P &p = door[t.x][t.y][i];
if (dis[p.x][p.y] == -1 && mat[p.x][p.y] != '#')
{
q.push(node{p.x, p.y, t.d + 3});
}
}
}
printf("%d\n", dis[tx][ty]);
}
return 0;
}