[USACO05DEC] Knights of Ni S
[USACO05DEC] Knights of Ni S
一道很水的搜索, 由于不想做题, 只能写写水题来放松一下了.
分别以贝茜和骑士为起点跑 BFS, 求出到每个灌木的最短距离, 然后枚举一遍取最小值就行了.
code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
return x * f;
}
struct Node {
int x, y;
inline Node (int a, int b) {
x = a, y = b;
}
inline Node operator + (const Node &a) const {
return Node(x + a.x, y + a.y);
}
};
const int N = 1e3 + 5;
int n, m, s[N][N], d1[N][N], d2[N][N], ans = 1 << 30;
Node st = Node(0, 0), ed = Node(0, 0), tmp[4] = {Node(-1, 0), Node(0, -1), Node(0, 1), Node(1, 0)};
queue <Node> q;
bool vis[N][N];
int main() {
m = read(), n = read();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
s[i][j] = read();
if (s[i][j] == 2) st = Node(i, j);
else if (s[i][j] == 3) ed = Node(i, j);
}
}
memset(d1, 0x3f, sizeof(d1));
memset(d2, 0x3f, sizeof(d2));
d1[st.x][st.y] = d2[ed.x][ed.y] = 0;
q.push(st);
vis[st.x][st.y] = 1;
while (q.size()) {
Node x = q.front(); q.pop();
for (int i = 0; i < 4; i++) {
Node y = x + tmp[i];
if (vis[y.x][y.y]) continue;
if (s[y.x][y.y] == 1 || s[y.x][y.y] == 3) continue;
if (y.x < 1 || y.x > n || y.y < 1 || y.y > m) continue;
vis[y.x][y.y] = 1;
q.push(y);
d1[y.x][y.y] = d1[x.x][x.y] + 1;
}
}
memset(vis, 0, sizeof(vis));
q.push(ed);
vis[ed.x][ed.y] = 1;
while (q.size()) {
Node x = q.front(); q.pop();
for (int i = 0; i < 4; i++) {
Node y = x + tmp[i];
if (vis[y.x][y.y]) continue;
if (s[y.x][y.y] == 1) continue;
if (y.x < 1 || y.x > n || y.y < 1 || y.y > m) continue;
vis[y.x][y.y] = 1;
q.push(y);
d2[y.x][y.y] = d2[x.x][x.y] + 1;
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (s[i][j] == 4) ans = min(ans, d1[i][j] + d2[i][j]);
}
}
printf("%d\n", ans);
return 0;
}
看不见我看不见我看不见我