이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, m, k, q;
cin >> n >> m >> k >> q;
vector<string> s(n);
for (int i = 0; i < n; i++) {
cin >> s[i];
}
vector<int> x(k);
vector<int> y(k);
for (int i = 0; i < k; i++) {
cin >> x[i] >> y[i];
--x[i]; --y[i];
}
vector<vector<int>> idx(n, vector<int>(m, -1));
vector<vector<int>> dist(n, vector<int>(m, 0));
vector<array<int, 4>> que;
for (int i = 0; i < k; i++) {
idx[x[i]][y[i]] = i;
dist[x[i]][y[i]] = 0;
que.push_back({x[i], y[i], 0, i});
}
auto Valid = [&](int x, int y) {
return 0 <= x && x < n && 0 <= y && y < m && s[x][y] != '#';
};
vector<vector<pair<int, int>>> g(k);
vector<int> par(k);
iota(par.begin(), par.end(), 0);
function<int(int)> GetPar = [&](int x) {
return par[x] == x ? x : par[x] = GetPar(par[x]);
};
auto Unite = [&](int x, int y, int w) {
if (GetPar(x) == GetPar(y)) {
return;
}
par[GetPar(x)] = GetPar(y);
g[x].push_back({y, w});
g[y].push_back({x, w});
};
vector<array<int, 3>> edges;
for (int b = 0; b < (int) que.size(); b++) {
int x = que[b][0];
int y = que[b][1];
int d = que[b][2];
int i = que[b][3];
for (int dir = 0; dir < 4; dir++) {
int nx = x + dx[dir];
int ny = y + dy[dir];
if (!Valid(nx, ny)) {
continue;
}
if (idx[nx][ny] != -1) {
edges.push_back({d + dist[nx][ny], i, idx[nx][ny]});
} else {
idx[nx][ny] = i;
dist[nx][ny] = d + 1;
que.push_back({nx, ny, d + 1, i});
}
}
}
sort(edges.begin(), edges.end());
for (auto& p : edges) {
Unite(p[1], p[2], p[0]);
}
const int L = 20;
vector<vector<int>> jump(k, vector<int>(L));
vector<vector<int>> up(k, vector<int>(L));
vector<int> dep(k, -1);
function<void(int, int)> Dfs = [&](int v, int pv) {
jump[v][0] = pv;
for (int i = 1; i < L; i++) {
jump[v][i] = jump[jump[v][i - 1]][i - 1];
}
dep[v] = dep[pv] + 1;
for (auto& p : g[v]) {
int to = p.first;
int w = p.second;
if (to == pv) {
continue;
}
up[to][0] = w;
Dfs(to, v);
}
};
for (int i = 0; i < k; i++) {
if (GetPar(i) == i) {
Dfs(i, i);
}
}
for (int j = 1; j < L; j++) {
for (int i = 0; i < k; i++) {
up[i][j] = max(up[i][j - 1], up[jump[i][j - 1]][j - 1]);
}
}
auto LCA = [&](int x, int y) {
if (dep[x] > dep[y]) {
swap(x, y);
}
for (int i = L - 1; i >= 0; i--) {
if (dep[jump[y][i]] >= dep[x]) {
y = jump[y][i];
}
}
for (int i = L - 1; i >= 0; i--) {
if (jump[x][i] != jump[y][i]) {
x = jump[x][i];
y = jump[y][i];
}
}
return x == y ? x : jump[x][0];
};
auto Query = [&](int x, int y) {
int d = dep[x] - dep[y];
int mx = 0;
for (int i = L - 1; i >= 0; i--) {
if (d >> i & 1) {
mx = max(mx, up[x][i]);
x = jump[x][i];
}
}
return mx;
};
while (q--) {
int a, b;
cin >> a >> b;
--a; --b;
if (GetPar(a) != GetPar(b)) {
cout << -1 << '\n';
continue;
}
int c = LCA(a, b);
cout << max(Query(a, c), Query(b, c)) << '\n';
}
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |