Problem p00465 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, j) FOR(i, 0, j)
#define mp std::make_pair

const int INF = 1 << 30;
const int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};

typedef unsigned long long ull;
typedef std::pair<int, int> P;
typedef std::pair<int, P> State;

int R, W[2], H[2], X[2], Y[2];
int Room[2][500][500];
std::map<int, int>
    maxR[2]; // maxR[i][j]: 事務所iでj番目に小さいレベルで行ける部屋の数
int used[500][500];

void travel(int r) {
  REP(j, H[r]) {
    REP(k, W[r]) { used[j][k] = 0; }
  }

  std::priority_queue<State, std::vector<State>, std::greater<State>> q;
  q.push(mp(1, mp(X[r], Y[r])));

  while (!q.empty()) {
    State s = q.top();
    q.pop();
    int l = s.first;
    P p = s.second;
    int x = p.first, y = p.second;

    if (used[y][x]) {
      continue;
    } else {
      used[y][x] = 1;
    }

    maxR[r][l]++;

    // std::cout << x << "," << y << "," << l << std::endl;

    REP(i, 4) {
      int nx = x + dx[i], ny = y + dy[i];
      if (0 <= nx && nx < W[r] && 0 <= ny && ny < H[r] && !used[ny][nx]) {

        int nl = std::max(l, Room[r][ny][nx]);
        q.push(mp(nl, mp(nx, ny)));
      }
    }
  }
}

int main() {
  while (std::cin >> R, R) {
    REP(i, 2) {
      std::cin >> W[i] >> H[i] >> X[i] >> Y[i];
      X[i]--;
      Y[i]--;

      maxR[i].clear();
      maxR[i][0] = 0;

      REP(j, H[i]) {
        REP(k, W[i]) { std::cin >> Room[i][j][k]; }
      }
    }

    REP(i, 2) { travel(i); }

    std::vector<int> u, v;
    int prev = 0;
    for (auto it = maxR[0].begin(); it != maxR[0].end(); it++) {
      u.push_back(it->first);
      v.push_back(prev + it->second);
      prev += it->second;
    }

    int res = INF;
    prev = 0;
    for (auto it = maxR[1].begin(); it != maxR[1].end(); it++) {
      int r2 = prev + it->second,
          r1_index = std::lower_bound(v.begin(), v.end(), R - r2) - v.begin();

      if (r1_index == v.size()) {
        continue;
      }

      res = std::min(res, it->first + u[r1_index]);
      prev += it->second;
    }

    std::cout << res << std::endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, j) FOR(i, 0, j)
#define mp std::make_pair

const int INF = 1 << 30;
const int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};

typedef unsigned long long ull;
typedef std::pair<int, int> P;
typedef std::pair<int, P> State;

int R, W[2], H[2], X[2], Y[2];
int Room[2][500][500];
std::vector<int> L[2]; // 事務所ごとの存在するレベル
int maxR[2][250001]; // maxR[i][j]: 事務所iでj番目に小さいレベルで行ける部屋の数
int used[500][500];

void travel(int r) {
  REP(j, H[r]) {
    REP(k, W[r]) { used[j][k] = 0; }
  }

  std::priority_queue<State, std::vector<State>, std::greater<State>> q;
  q.push(mp(1, mp(X[r], Y[r])));
  used[Y[r]][X[r]] = 1;
  maxR[r][1] = 1;

  while (!q.empty()) {
    State s = q.top();
    q.pop();
    int l = s.first;
    P p = s.second;
    int x = p.first, y = p.second;

    // std::cout << x << "," << y << "," << l << std::endl;

    REP(i, 4) {
      int nx = x + dx[i], ny = y + dy[i];
      if (0 <= nx && nx < W[r] && 0 <= ny && ny < H[r] && !used[ny][nx]) {

        int nl = std::max(l, Room[r][ny][nx]),
            nl_index = std::distance(L[r].begin(),
                                     std::find(L[r].begin(), L[r].end(), nl));

        q.push(mp(nl, mp(nx, ny)));
        used[ny][nx] = 1;
        maxR[r][nl_index]++;
      }
    }
  }
}

int main() {
  while (std::cin >> R, R) {
    REP(i, 2) {
      std::cin >> W[i] >> H[i] >> X[i] >> Y[i];
      X[i]--;
      Y[i]--;

      L[i].clear();
      L[i].push_back(0);
      REP(j, H[i]) {
        REP(k, W[i]) {
          std::cin >> Room[i][j][k];
          L[i].push_back(Room[i][j][k]);
        }
      }

      std::sort(L[i].begin(), L[i].end());
      L[i].erase(std::unique(L[i].begin(), L[i].end()), L[i].end());
    }

    REP(i, 2) {
      REP(j, L[i].size()) { maxR[i][j] = 0; }
    }

    REP(i, 2) { travel(i); }

    REP(i, 2) {
      // std::cout << maxR[i][0] << std::endl;
      FOR(j, 1, L[i].size()) {
        maxR[i][j] += maxR[i][j - 1];
        // std::cout << maxR[i][j] << std::endl;
      }
      // puts("##############################");
    }

    int res = INF;
    REP(i, L[0].size()) {
      int r1 = maxR[0][i],
          r2_index = std::lower_bound(maxR[1], maxR[1] + L[1].size(), R - r1) -
                     maxR[1];

      if (r2_index == L[1].size()) {
        continue;
      }

      res = std::min(res, L[0][i] + L[1][r2_index]);
    }

    std::cout << res << std::endl;
  }
}