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

#include <algorithm>
#include <map>
#include <queue>
#include <stdio.h>
#include <vector>
using namespace std;
typedef pair<int, int> P;
int w[2];
int h[2];
int x[2];
int y[2];
int t[2][500][500];
int m[2][500][500];
bool used[2][500][500];
vector<int> ad[2];
priority_queue<P, vector<P>, greater<P>> que;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
void bfs(int a) {
  int i;
  m[a][y[a]][x[a]] = 1;
  que.push(P(1, y[a] * w[a] + x[a]));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int xp = p.second % w[a];
    int yp = p.second / w[a];
    if (p.first > m[a][yp][xp])
      continue;
    used[a][yp][xp] = true;
    for (i = 0; i < 4; i++) {
      if (xp + dx[i] >= 0 && xp + dx[i] < w[a] && yp + dy[i] >= 0 &&
          yp + dy[i] < h[a]) {
        if (!used[a][yp + dy[i]][xp + dx[i]] &&
            m[a][yp + dy[i]][xp + dx[i]] >
                max(p.first, t[a][yp + dy[i]][xp + dx[i]])) {
          m[a][yp + dy[i]][xp + dx[i]] =
              max(p.first, t[a][yp + dy[i]][xp + dx[i]]);
          que.push(P(m[a][yp + dy[i]][xp + dx[i]],
                     (yp + dy[i]) * w[a] + (xp + dx[i])));
        }
      }
    }
  }
}
int main() {
  int r;
  int i, j, k;
  while (1) {
    scanf("%d", &r);
    if (r == 0)
      return 0;
    for (i = 0; i < 2; i++) {
      scanf("%d %d %d %d", &w[i], &h[i], &x[i], &y[i]);
      x[i]--;
      y[i]--;
      for (j = 0; j < h[i]; j++)
        for (k = 0; k < w[i]; k++)
          scanf("%d", &t[i][j][k]);
    }
    for (i = 0; i < 2; i++) {
      for (j = 0; j < h[i]; j++)
        for (k = 0; k < w[i]; k++) {
          m[i][j][k] = 200000000;
          used[i][j][k] = false;
        }
      bfs(i);
    }
    for (i = 0; i < 2; i++) {
      ad[i].clear();
      ad[i].push_back(0);
      for (j = 0; j < h[i]; j++) {
        for (k = 0; k < w[i]; k++) {
          ad[i].push_back(m[i][j][k]);
        }
      }
      sort(ad[i].begin(), ad[i].end());
    }
    int ans = 200000000;
    i = max(0, r - ad[1].size() + 1);
    while (1) {
      if (i >= ad[0].size() || r - i >= ad[1].size())
        break;
      ans = min(ans, ad[0][i] + ad[1][r - i]);
      i++;
    }
    printf("%d\\n", ans);
  }
}

Error: TLE

Fixed submission:

#include <stdio.h>
#include <stdlib.h>
#define INF 100000001
typedef struct {
  int x, y;
  int lev;
} data;
data d[25000];
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
int comp(const void *a, const void *b) {
  data *p = (data *)a;
  data *q = (data *)b;
  return p->lev - q->lev;
}
int comp2(const void *a, const void *b) {
  int *p = (int *)a;
  int *q = (int *)b;
  return *p - *q;
}
int cd;
int level[2][500][500];
int mlevel[2][500][500];
int mlevel2[2][25000];
typedef struct {
  int val;
  int time;
} poss;
poss pos[2][25001];
int cpos[2];
int sx[2];
int sy[2];
int w[2];
int h[2];
bool used[500][500];
int dx[4] = {-1, 0, 0, 1};
int dy[4] = {0, 1, -1, 0};
int main() {
  int r, x, y;
  int i, j, k;
  while (1) {
    scanf("%d", &r);
    if (r == 0)
      return 0;
    for (i = 0; i < 2; i++) {
      scanf("%d %d %d %d", &w[i], &h[i], &x, &y);
      sx[i] = x - 1;
      sy[i] = y - 1;
      for (j = 0; j < h[i]; j++)
        for (k = 0; k < w[i]; k++)
          scanf("%d", &level[i][j][k]);
    }
    cpos[0] = 0;
    cpos[1] = 0;
    for (i = 0; i < 2; i++)
      for (j = 0; j < h[i]; j++)
        for (k = 0; k < w[i]; k++)
          mlevel[i][j][k] = 0;
    for (i = 0; i < 2; i++) {
      cd = 0;
      for (j = 0; j < h[i]; j++)
        for (k = 0; k < w[i]; k++)
          used[j][k] = false;
      data da;
      da.x = sx[i];
      da.y = sy[i];
      da.lev = level[i][sy[i]][sx[i]];
      d[cd++] = da;
      used[sy[i]][sx[i]] = true;
      for (j = 0; j < w[i] * h[i]; j++) {
        qsort(d, cd, sizeof(data), comp);
        mlevel[i][d[0].y][d[0].x] = d[0].lev;
        d[0].lev = INF;
        for (k = 0; k < 4; k++) {
          if (d[0].x + dx[k] >= 0 && d[0].x + dx[k] < w[i] &&
              d[0].y + dy[k] >= 0 && d[0].y + dy[k] < h[i] &&
              !used[d[0].y + dy[k]][d[0].x + dx[k]]) {
            mlevel[i][d[0].y + dy[k]][d[0].x + dx[k]] =
                max(mlevel[i][d[0].y + dy[k]][d[0].x + dx[k]],
                    max(level[i][d[0].y + dy[k]][d[0].x + dx[k]],
                        mlevel[i][d[0].y][d[0].x]));
            if (!used[d[0].y + dy[k]][d[0].x + dx[k]]) {
              data dat;
              dat.x = d[0].x + dx[k];
              dat.y = d[0].y + dy[k];
              dat.lev = mlevel[i][d[0].y + dy[k]][d[0].x + dx[k]];
              d[cd++] = dat;
              used[d[0].y + dy[k]][d[0].x + dx[k]] = true;
            }
          }
        }
      }
      int old = -1;
      for (j = 0; j < h[i] * w[i]; j++)
        pos[i][j].time = 0;
      for (j = 0; j < h[i]; j++)
        for (k = 0; k < w[i]; k++)
          mlevel2[i][j * w[i] + k] = mlevel[i][j][k];
      qsort(mlevel2[i], w[i] * h[i], sizeof(int), comp2);
      for (j = 0; j < w[i] * h[i]; j++) {
        if (mlevel2[i][j] != old) {
          pos[i][++cpos[i]].time = 1;
          pos[i][cpos[i]].time += pos[i][cpos[i] - 1].time;
          old = mlevel2[i][j];
          pos[i][cpos[i]].val = old;
        } else
          pos[i][cpos[i]].time++;
      }
    }
    int ans = INF;
    int s;
    int g;
    int mid;
    int res;
    for (i = 1; i <= cpos[0]; i++) {
      res = r - pos[0][i].time;
      if (res < 0) {
        ans = min(ans, pos[0][i].val);
        continue;
      }
      s = 0;
      g = cpos[1] + 1;
      for (j = 0; j < 40; j++) {
        mid = (int)(s + g) / 2;
        if (pos[1][mid].time == res)
          break;
        else if (pos[1][mid].time < res)
          s = mid;
        else
          g = mid;
      }
      mid = (int)(s + g) / 2;
      if (pos[0][i].time + pos[1][mid].time >= r) {
        ans = min(ans, pos[0][i].val + pos[1][mid].val);
      }
    }
    printf("%d\\n", ans);
  }
}