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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 29)
#define all(n) (n).begin(), (n).end()
#define MAX 501
using namespace std;

struct P {
  int x, y;
  P(int x = inf, int y = inf) : x(x), y(y) {}
  bool operator<(const P &a) const { return (x != a.x ? x < a.x : y < a.y); }
};

struct Pox {
  int x, y, level;
  Pox(int x = inf, int y = inf, int level = inf, int index = inf)
      : x(x), y(y), level(level) {}
  bool operator<(const Pox &a) const { return level > a.level; }
};

typedef pair<int, int> ii;

int R;
int room[2][MAX][MAX];
int ex[2], ey[2];
int h[2], w[2];
vector<int> level[2];
vector<ii> vec[2];
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
// int COST[2];
// deque<P> deq[2];
bool visited[2][MAX][MAX];
int sum[2][MAX * MAX];
map<int, int> dict[2];

void init() {
  rep(i, 2) {
    dict[i].clear();
    level[i].clear();
    vec[i].clear();
    rep(j, MAX) rep(k, MAX) { visited[i][j][k] = false; }
    rep(j, MAX * MAX) sum[i][j] = 0;
  }
}

void compute_cost(int sp) {
  int N = level[sp].size();
  int H = h[sp], W = w[sp];
  priority_queue<Pox> Q;

  rep(i, H) rep(j, W) visited[sp][i][j] = false, sum[sp][i * W + W] = 0;

  Q.push(Pox(ex[sp], ey[sp], 1));
  // sum[sp][dict[sp][1]]++;
  visited[sp][ey[sp]][ex[sp]] = true;
  int dex = 1;
  while (!Q.empty()) {
    Pox pox = Q.top();
    Q.pop();
    // cout << "add
    // sum["<<sp<<"][dict["<<sp<<"]["<<*lower_bound(all(level[sp]),pox.level)<<"]]
    // : " << dict[sp][*lower_bound(all(level[sp]),pox.level)] << endl;
    // sum[sp][dict[sp][*lower_bound(all(level[sp]),pox.level)]]++;
    dex = max(dex, pox.level);
    sum[sp][dict[sp][dex]]++;
    // ut << "pox = " << pox.x << "," << pox.y << " " << pox.level << endl;

    rep(i, 4) {
      int nx = pox.x + dx[i];
      int ny = pox.y + dy[i];
      if (!(0 <= nx && nx < W && 0 <= ny && ny < H))
        continue;
      if (visited[sp][ny][nx])
        continue;
      visited[sp][ny][nx] = true;
      Q.push(Pox(nx, ny, room[sp][ny][nx]));
    }
  }
}

/*
int getCost(int sp,int l)
{
  if(room[sp][ey[sp]][ex[sp]] > l)return 0;

  int H = h[sp], W = w[sp];

  deque<P> store;
  //cout << "IN : level " << l << endl;

  while(!deq[sp].empty())
    {
      P p = deq[sp].front(); deq[sp].pop_front();

      rep(i,4)
        {
          int nx = p.x + dx[i];
          int ny = p.y + dy[i];
          if(!(0 <= nx && nx < W && 0 <= ny && ny < H))continue;
          if(room[sp][ny][nx] > l)continue;
          if(!visited[sp][ny][nx])
            {
              //cout << "from " << p.x << "," << p.y << " goto " << nx << "," <<
ny << " level is "<< room[sp][ny][nx] << endl; visited[sp][ny][nx] = true;
              deq[sp].push_back(P(nx,ny));
              COST[sp]++;
            }
        }

      bool update = false;
      rep(i,4)
        {
          int nx = p.x + dx[i];
          int ny = p.y + dy[i];
          if(!(0 <= nx && nx < W && 0 <= ny && ny < H))continue;
          if(visited[sp][ny][nx])continue;
          update = true;
          break;
        }
      if(update)store.push_back(p);
    }
  deq[sp] = store;
  return COST[sp];
}
*/

void compute() {
  /*
  rep(i,2)
    {
      COST[i] = 0;
      deq[i].clear();
      deq[i].push_back(P(ex[i],ey[i]));
      visited[i][ey[i]][ex[i]] = true;
      vec[i].push_back(ii(0,0));
      rep(y,h[i])rep(x,w[i])visited[i][y][x] = false;

      rep(j,level[i].size())
        {
          int cost = getCost(i,level[i][j]);
          vec[i].push_back(ii(cost,level[i][j]));
        }
      sort(all(vec[i]));
    }
  */

  rep(i, 2) {
    compute_cost(i);
    // cout << "finish - " << i << endl;
    // cout << "fsee sum ---- "<< endl;
    /*
    rep(j,level[i].size())
      {
        cout << j << "-th " << sum[i][j] << endl;
      }
    */
    REP(j, 1, level[i].size()) sum[i][j] += sum[i][j - 1];
    /*
    cout << "see sum ---- "<< endl;
    rep(j,level[i].size())
      {
        cout << j << "-th " << sum[i][j] << endl;
      }
    */
    rep(j, level[i].size()) vec[i].push_back(ii(sum[i][j], level[i][j]));
  }
  /*
  rep(i,2)
    {
      rep(j,vec[i].size())
        {
          cout << "vec["<<i<<"]["<<j<<"] = (" << vec[i][j].first << "," <<
  vec[i][j].second << ")\\n";
        }
    }
  */

  int minlevel = inf;
  rep(i, vec[0].size()) {
    int lvl = vec[0][i].second;
    int cost = vec[0][i].first;
    int request = R - cost;
    if (request <= 0) {
      minlevel = min(minlevel, lvl);
      continue;
    }

    if (lower_bound(all(vec[1]), ii(request, -1)) == vec[1].end())
      continue;
    ii store = *lower_bound(all(vec[1]), ii(request, -1));
    int nlvl = store.second;
    int ncost = store.first;

    minlevel = min(minlevel, lvl + nlvl);
  }
  cout << minlevel << endl;
}

int main() {
  while (cin >> R, R) {
    init();
    rep(i, 2) {
      dict[i].clear();
      level[i].clear(), vec[i].clear();
      cin >> w[i] >> h[i] >> ex[i] >> ey[i];
      ex[i]--, ey[i]--;
      rep(y, h[i]) rep(x, w[i]) cin >> room[i][y][x],
          level[i].push_back(room[i][y][x]);
      sort(all(level[i]));
      level[i].erase(unique(all(level[i])), level[i].end());
      rep(j, level[i].size()) dict[i][level[i][j]] = j;
    }
    compute();
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <deque>
#include <iostream>
#include <queue>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 29)
#define all(n) (n).begin(), (n).end()
#define MAX 501
using namespace std;

struct P {
  int x, y;
  P(int x = inf, int y = inf) : x(x), y(y) {}
  bool operator<(const P &a) const { return (x != a.x ? x < a.x : y < a.y); }
};

typedef pair<int, int> ii;

int R;
int room[2][MAX][MAX];
int ex[2], ey[2];
int h[2], w[2];
vector<int> level[2];
vector<ii> vec[2];
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
int COST[2];
deque<P> deq[2];
bool visited[2][MAX][MAX];

int getCost(int sp, int l) {
  if (room[sp][ey[sp]][ex[sp]] > l)
    return 0;

  int H = h[sp], W = w[sp];

  deque<P> store;
  // cout << "IN : level " << l << endl;

  while (!deq[sp].empty()) {
    P p = deq[sp].front();
    deq[sp].pop_front();

    rep(i, 4) {
      int nx = p.x + dx[i];
      int ny = p.y + dy[i];
      if (!(0 <= nx && nx < W && 0 <= ny && ny < H))
        continue;
      if (room[sp][ny][nx] > l)
        continue;
      if (!visited[sp][ny][nx]) {
        // cout << "from " << p.x << "," << p.y << " goto " << nx << "," << ny
        // << " level is "<< room[sp][ny][nx] << endl;
        visited[sp][ny][nx] = true;
        deq[sp].push_back(P(nx, ny));
        COST[sp]++;
      }
    }

    bool update = false;
    rep(i, 4) {
      int nx = p.x + dx[i];
      int ny = p.y + dy[i];
      if (!(0 <= nx && nx < W && 0 <= ny && ny < H))
        continue;
      if (visited[sp][ny][nx])
        continue;
      update = true;
      break;
    }
    if (update)
      store.push_back(p);
  }
  deq[sp] = store;
  return COST[sp];
}

void compute() {
  rep(i, 2) {
    COST[i] = 0;
    deq[i].clear();
    deq[i].push_back(P(ex[i], ey[i]));
    visited[i][ey[i]][ex[i]] = true;
    vec[i].push_back(ii(0, 0));
    rep(y, h[i]) rep(x, w[i]) visited[i][y][x] = false;

    rep(j, level[i].size()) {
      int cost = getCost(i, level[i][j]);
      vec[i].push_back(ii(cost, level[i][j]));
    }
    sort(all(vec[i]));
  }

  /*
  rep(i,2)
    {
      rep(j,vec[i].size())
        {
          cout << "vec["<<i<<"]["<<j<<"] = (" << vec[i][j].first << "," <<
  vec[i][j].second << ")\\n";
        }
    }
  */

  int minlevel = inf;
  rep(i, vec[0].size()) {
    int lvl = vec[0][i].second;
    int cost = vec[0][i].first;
    int request = R - cost;
    if (request <= 0) {
      minlevel = min(minlevel, lvl);
      continue;
    }

    if (lower_bound(all(vec[1]), ii(request, -1)) == vec[1].end())
      continue;
    ii store = *lower_bound(all(vec[1]), ii(request, -1));
    int nlvl = store.second;
    int ncost = store.first;

    minlevel = min(minlevel, lvl + nlvl);
  }
  cout << minlevel << endl;
}

int main() {
  while (cin >> R, R) {
    rep(i, 2) {
      level[i].clear(), vec[i].clear();
      cin >> w[i] >> h[i] >> ex[i] >> ey[i];
      ex[i]--, ey[i]--;
      rep(y, h[i]) rep(x, w[i]) cin >> room[i][y][x],
          level[i].push_back(room[i][y][x]);
      sort(all(level[i]));
      level[i].erase(unique(all(level[i])), level[i].end());
    }
    compute();
  }
  return 0;
}