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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <queue>
#include <vector>
#define MAX_H 504
#define MAX_W 504
#define MAX_LEVEL 100000000
#define mp make_pair
#define INF 1001001001
#define ppp pair<int, pair<int, int>>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
vector<int> LEVEL_ABILITY[2];
vector<int> LEVEL_ABILITY_UNIQUE[2];
vector<int> LEVEL_ABILITY_BOX[2];
int main(void) {
  while (1) {
    LEVEL_ABILITY_UNIQUE[0].clear();
    LEVEL_ABILITY_UNIQUE[1].clear();
    LEVEL_ABILITY[0].clear();
    LEVEL_ABILITY[1].clear();
    LEVEL_ABILITY_BOX[0].clear();
    LEVEL_ABILITY_BOX[1].clear();
    int R;
    scanf("%d", &R);
    if (R == 0)
      break;
    rep(i, 2) {
      int W, H, X, Y;
      int LEVEL[MAX_H][MAX_W];
      int DLEVEL[MAX_H][MAX_W];
      scanf("%d %d %d %d", &W, &H, &X, &Y);
      X--;
      Y--;
      rep(j, H) rep(k, W) {
        scanf("%d", &LEVEL[j][k]);
        DLEVEL[j][k] = INF;
      }
      // 探索
      priority_queue<ppp, vector<ppp>, greater<ppp>> D;
      D.push(mp(1, mp(Y, X)));
      while (!D.empty()) {
        pair<int, pair<int, int>> p = D.top();
        D.pop();
        int pL = p.first;
        int pY = p.second.first;
        int pX = p.second.second;
        if (pL >= DLEVEL[pY][pX])
          continue;
        DLEVEL[pY][pX] = max(pL, LEVEL[pY][pX]);
        if (pY > 0)
          D.push(mp(DLEVEL[pY][pX], mp(pY - 1, pX)));
        if (pY < H - 1)
          D.push(mp(DLEVEL[pY][pX], mp(pY + 1, pX)));
        if (pX > 0)
          D.push(mp(DLEVEL[pY][pX], mp(pY, pX - 1)));
        if (pX < W - 1)
          D.push(mp(DLEVEL[pY][pX], mp(pY, pX + 1)));
      }
      // LEVEL_ABILITYを作る
      LEVEL_ABILITY[i].push_back(0);
      rep(j, H) rep(k, W) { LEVEL_ABILITY[i].push_back(DLEVEL[j][k]); }
      sort(LEVEL_ABILITY[i].begin(), LEVEL_ABILITY[i].end());
      // rep(test,LEVEL_ABILITY[i].size()
      // ){printf("%d-",LEVEL_ABILITY[i][test]);}
      LEVEL_ABILITY_UNIQUE[i] = LEVEL_ABILITY[i];
      LEVEL_ABILITY_UNIQUE[i].erase(unique(LEVEL_ABILITY_UNIQUE[i].begin(),
                                           LEVEL_ABILITY_UNIQUE[i].end()),
                                    LEVEL_ABILITY_UNIQUE[i].end());
      int ite = 1;
      rep(j, LEVEL_ABILITY[i].size()) {
        if (j == 0) {
          LEVEL_ABILITY_BOX[i].push_back(0);
          continue;
        }
        if (LEVEL_ABILITY[i][j] != LEVEL_ABILITY[i][ite]) {
          LEVEL_ABILITY_BOX[i].push_back(j - 1);
          ite = j;
        }
        if (j == LEVEL_ABILITY[i].size() - 1) {
          LEVEL_ABILITY_BOX[i].push_back(j);
        }
      }
      LEVEL_ABILITY_UNIQUE[i].push_back(INF);
    }
    // 一件目の認定レベルを決め、二回目に何個行けるか調べる。
    int ans = INF;
    rep(i, LEVEL_ABILITY_UNIQUE[0].size()) {
      int firstLV = LEVEL_ABILITY_UNIQUE[0][i];
      int firstscore = LEVEL_ABILITY_BOX[0][i];
      int secondscore = R - firstscore;
      int secondLV;
      if (secondscore <= 0)
        secondLV = 0;
      else {
        int ite = lower_bound(LEVEL_ABILITY_BOX[1].begin(),
                              LEVEL_ABILITY_BOX[1].end(), secondscore) -
                  LEVEL_ABILITY_BOX[1].begin();
        secondLV = LEVEL_ABILITY_UNIQUE[1][ite];
      }
      ans = min(ans, firstLV + secondLV);
    }
    printf("%d\\n", ans);
  }
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;
// #define int long long
#define rep(i, n) for (int i = 0; i < n; i++)
#define mp make_pair
const int INF = 1001001001;
int W[2], H[2], X[2], Y[2];
int L[2][502][502];
vector<int> levs[2]; //????????????????¨???¬??????sorted
vector<int>
    levtoheya[2]; //???????????¨????????¬?????????????????????????????¨?±??????°
int solve() {
  int R;
  scanf("%d", &R);
  if (R == 0)
    return -1;
  rep(k, 2) {
    if (levs[k].size())
      levs[k].clear();
    if (levtoheya[k].size())
      levtoheya[k].clear();
    levs[k].push_back(0);
    scanf("%d %d %d %d", &W[k], &H[k], &X[k], &Y[k]);
    X[k]--;
    Y[k]--;
    rep(i, H[k]) {
      rep(j, W[k]) {
        scanf("%d", &L[k][j][i]);
        levs[k].push_back(L[k][j][i]);
      }
    }
    sort(levs[k].begin(), levs[k].end());
    levs[k].erase(unique(levs[k].begin(), levs[k].end()), levs[k].end());
  }
  rep(k, 2) {
    int heya = 1; //??????????????¨?±???°
    queue<pair<int, int>> q1;
    queue<pair<int, int>> q2;
    queue<pair<int, int>> qnull;
    q2.push(mp(X[k], Y[k]));
    bool ifgo[500][500];
    fill(ifgo[0], ifgo[500], false);
    ifgo[X[k]][Y[k]] = true;
    rep(x,
        levs[k]
            .size()) { //????????????x????¢???????????????¨?????????????????¨?±??????°??????????¢????
      if (x == 0) {
        levtoheya[k].push_back(0);
        continue;
      }
      int NX = levs[k][x];
      // que2?????????????????????(??¨??????????????\\????????¨?±??????????)?????¨?±????????????¬??????x?????¨?±??????????????????¨?±???°????¢???????
      q1 = q2;
      q2 = qnull;
      while (q1.size()) {
        pair<int, int> n = q1.front();
        q1.pop();
        int nx = n.first;
        int ny = n.second;
        bool ifaround = false;
        if (nx > 0) {
          if (L[k][nx - 1][ny] <= NX) {
            if (!ifgo[nx - 1][ny]) {
              q1.push(mp(nx - 1, ny));
              ifgo[nx - 1][ny] = true;
              heya++;
            }
          } else
            ifaround = true;
        }
        if (ny > 0) {
          if (L[k][nx][ny - 1] <= NX) {
            if (!ifgo[nx][ny - 1]) {
              q1.push(mp(nx, ny - 1));
              ifgo[nx][ny - 1] = true;
              heya++;
            }
          } else
            ifaround = true;
        }
        if (nx + 1 < W[k]) {
          if (L[k][nx + 1][ny] <= NX) {
            if (!ifgo[nx + 1][ny]) {
              q1.push(mp(nx + 1, ny));
              ifgo[nx + 1][ny] = true;
              heya++;
            }
          } else
            ifaround = true;
        }
        if (ny + 1 < H[k]) {
          if (L[k][nx][ny + 1] <= NX) {
            if (!ifgo[nx][ny + 1]) {
              q1.push(mp(nx, ny + 1));
              ifgo[nx][ny + 1] = true;
              heya++;
            }
          } else
            ifaround = true;
        }
        if (ifaround) {
          q2.push(mp(nx, ny));
        }
      }
      levtoheya[k].push_back(heya);
    }
  }
  // levtoheya??????????????????????????????????±???????
  int ans = INF;
  rep(i, levtoheya[0].size()) {
    int mi = lower_bound(levtoheya[1].begin(), levtoheya[1].end(),
                         R - levtoheya[0][i]) -
             levtoheya[1].begin();
    if (mi >= levtoheya[1].size())
      continue;
    int sans = levs[0][i] + levs[1][mi];
    ans = min(ans, sans);
  }
  return ans;
}
signed main() {
  while (1) {
    int ans = solve();
    if (ans < 0)
      break;
    printf("%d\\n", ans);
  }
  return 0;
}