이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) 42
#endif
const int N = 2e3 + 5, MAX = 2e5 + 5;
const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int n, m, p, q;
int lab[N][N], d[N][N], res[MAX], s[MAX], t[MAX], pr[MAX];
char a[N][N];
vector<int> queries[MAX], ver[MAX];
bool inside(int i, int j) {
  return 0 < i && i <= n && 0 < j && j <= m && a[i][j] != '#';
}
void mrg(int u, int v, int w) {
  if ((u = pr[u]) != (v = pr[v])) {
    if (ver[u].size() < ver[v].size()) {
      swap(u, v);
    }
    for (int x : ver[v]) {
      pr[x] = u;
      ver[u].push_back(x);
    }
    for (auto id : queries[v]) {
      if (pr[s[id]] == pr[t[id]] && res[id] == -1) {
        res[id] += w;
      } else {
        queries[u].push_back(id);
      }
    }
  }
}
int main() {
  ios::sync_with_stdio(false); cin.tie(nullptr);
  cin >> n >> m >> p >> q;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      cin >> a[i][j];
    }
  }
  queue<array<int, 2>> que;
  for (int i = 1; i <= p; ++i) {
    int r, c; cin >> r >> c;
    lab[r][c] = i;
    que.push({r, c});
  }
  while (que.size()) {
    auto [x, y] = que.front(); que.pop();
    for (int dr = 0; dr < 4; ++dr) {
      int i = x + dx[dr], j = y + dy[dr];
      if (inside(i, j) && !lab[i][j]) {
        lab[i][j] = lab[x][y];
        d[i][j] = d[x][y] + 1;
        que.push({i, j});
      }
    }
  }
  vector<array<int, 3>> edges;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      if (lab[i][j]) {
        for (int dr = 0; dr < 4; ++dr) {
          int x = i + dx[dr], y = j + dy[dr];
          if (inside(x, y) && lab[x][y] != lab[i][j]) {
            edges.push_back({d[x][y] + d[i][j] + 1, lab[i][j], lab[x][y]});
          }
        }
      }
    }
  }
  for (int i = 1; i <= p; ++i) {
    ver[i].push_back(i);
    pr[i] = i; 
  }
  for (int i = 1; i <= q; ++i) {
    cin >> s[i] >> t[i];
    res[i] = -1;
    queries[s[i]].push_back(i);
    queries[t[i]].push_back(i);
  }
  sort(edges.begin(), edges.end());
  for (auto [w, u, v] : edges) {
    mrg(u, v, w);
  }
  for (int i = 1; i <= q; ++i) {
    cout << res[i] << "\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... |