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

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <vector>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); i++)
#define reps(i, n) for (int i = 1; i <= int(n); i++)

vector<int> need[2];
int masu[555][555];
int visit[555][555];
class S {
public:
  int x, y;
  int n;
  S(int x, int y, int n) : x(x), y(y), n(n){};
  bool operator<(const S &a) const { return n > a.n; }
};
int main() {
  while (1) {
    int n;
    cin >> n;
    if (n == 0)
      break;
    int dx[] = {1, 0, -1, 0};
    int dy[] = {0, 1, 0, -1};
    need[0].clear();
    need[1].clear();
    rep(p, 2) {
      int a, b, c, d;
      cin >> a >> b >> c >> d;
      rep(i, b) {
        rep(j, a) { cin >> masu[j][i]; }
      }
      rep(i, b) {
        rep(j, a) { visit[j][i] = 0; }
      }
      priority_queue<S> que;
      que.push(S(c - 1, d - 1, 1));
      need[p].push_back(0);
      int now = -1;
      while (1) {
        if (que.empty() == 1) {
          break;
        }
        S u = que.top();
        que.pop();
        if (u.x < 0 || u.y < 0 || u.y >= b || u.x >= a)
          continue;
        if (visit[u.x][u.y] == 1) {
          continue;
        }
        // printf("!%d %d %d\\n",u.x,u.y,u.n);
        visit[u.x][u.y] = 1;
        now = max(now, masu[u.x][u.y]);
        need[p].push_back(now);

        rep(i, 4) {
          que.push(S(u.x + dx[i], u.y + dy[i], masu[u.x + dx[i]][u.y + dy[i]]));
        }
      }
    }
    /*
    rep(i,2){
      rep(j,need[i].size()){
        printf("%d\\n",need[i][j]);
      }puts("");
      }*/
    int ans = 101000000;
    rep(i, max(need[0].size(), need[1].size())) {
      if (i >= need[0].size())
        continue;
      if (n - i < 0)
        continue;
      if (n - i >= need[1].size())
        continue;
      ans = min(ans, need[0][i] + need[1][n - i]);
    }
    printf("%d\\n", ans);
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>

using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
#define reps(i, n) for (int i = 1; i <= n; i++)

const int INF = 1010000000;

int R;
int w[2], h[2], st[2], gl[2];
int masu[2][501][501];

int need[2][25001];

int visit[501][501];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int glcont;

void saiki(int w, int h, int x, int y, int masu[501][501], int mn) {
  if (x < 0 || y < 0 || x >= w || y >= h)
    return;
  if (masu[x][y] > mn)
    return;
  if (visit[x][y] == 1)
    return;
  visit[x][y] = 1;

  rep(i, 4) { saiki(w, h, x + dx[i], y + dy[i], masu, mn); }

  glcont++;
}

int main() {
  while (1) {
    scanf("%d", &R);
    if (R == 0)
      break;

    rep(i, 2) {
      scanf("%d%d%d%d", &w[i], &h[i], &st[i], &gl[i]);

      rep(j, h[i]) {
        rep(k, w[i]) { scanf("%d", &masu[i][k][j]); }
      }
    }

    int left, right;
    left = 0;
    right = 1000000001;
    rep(i, 2) rep(j, 250001) need[i][j] = INF;
    rep(i, 2) {
      rep(n, w[i] * h[i] + 1) {
        int left, right;
        left = 0;
        right = 1000000001;

        while (1) {
          double half = double(left + right) / 2.0;
          rep(rr, w[i]) rep(ee, h[i]) visit[rr][ee] = 0;
          glcont = 0;

          saiki(w[i], h[i], st[i] - 1, gl[i] - 1, masu[i], int(half));

          if (glcont < n) {
            left = half;
          } else {
            right = int(half - 0.5);
          }

          if (left == right) {
            break;
          }
        }
        need[i][n] = left;
      }
    }

    int mini = INF * 2 + 1;

    int dd = 0;
    if (w[0] * h[0] < w[1] + h[1]) {
      dd = 1;
    }

    rep(i, 250001) {
      if (R - i < 0)
        break;
      mini = min(mini, need[dd][i] + need[!dd][R - i]);
    }
    /*
    rep(i,2){
            puts("");
            rep(n,w[i]*h[i]+1){
                    printf("%d %d\\n",n,need[i][n]);
            }
    }*/
    printf("%d\\n", mini);
  }
}