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

#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <functional>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)

const int dx[4] = {-1, 0, 0, 1}, dy[4] = {0, -1, 1, 0};
int H, W, M[1234][1234];
vector<vector<int>> water;
vector<set<int>> water_to;
vector<bool> isOne;

int index(int w, int h) {
  if (w < 0 || h < 0 || w >= W || h >= H)
    return -1;
  return h * W + w;
}

void GetWaterTo(int i) {
  if (water_to[i].size() > 0 || isOne[i])
    return;
  if (water[i].size() == 0)
    water_to[i].insert(i);
  rep(j, water[i].size()) {
    GetWaterTo(water[i][j]);
    if (isOne[water[i][j]] || water_to[water[i][j]].size() >= 2) {
      isOne[i] = true;
      break;
    }
    water_to[i].insert(water_to[water[i][j]].begin(),
                       water_to[water[i][j]].end());
  }
  return;
}

int main() {

  scanf("%d %d", &H, &W);

  water.resize(H * W);
  water_to.resize(H * W);
  isOne.resize(H * W, false);

  vector<pair<int, int>> order;

  int IndexCount = 0;
  rep(i, H) rep(j, W) {
    scanf("%d", &M[i][j]);
    order.push_back(make_pair(M[i][j], IndexCount));
    IndexCount++;
  }

  rep(i, H) rep(j, W) {
    rep(d, 4) {
      if (index(j + dx[d], i + dy[d]) != -1 &&
          M[i][j] > M[i + dy[d]][j + dx[d]]) {
        water[index(j, i)].push_back(index(j + dx[d], i + dy[d]));
      }
    }
  }

  sort(order.begin(), order.end());

  rep(i, order.size()) GetWaterTo(order[i].second);
  // rep(i, H*W) GetWaterTo(i);

  int c = 0;
  rep(i, H * W) if (isOne[i] || water_to[i].size() >= 2) c++;

  printf("%d\\n", c);

  return 0;
}

Error: TLE

Fixed submission:

#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <functional>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)

const int dx[4] = {-1, 0, 0, 1}, dy[4] = {0, -1, 1, 0};
int H, W, M[1234][1234];
vector<vector<int>> water;
vector<set<int>> water_to;
vector<bool> isOne;

int index(int w, int h) {
  if (w < 0 || h < 0 || w >= W || h >= H)
    return -1;
  return h * W + w;
}

void GetWaterTo(int i) {
  if (water_to[i].size() > 0)
    return;
  if (water[i].size() == 0)
    water_to[i].insert(i);
  rep(j, water[i].size()) {
    GetWaterTo(water[i][j]);
    if (isOne[water[i][j]] || water_to[water[i][j]].size() >= 2) {
      isOne[i] = true;
      break;
    }
    water_to[i].insert(water_to[water[i][j]].begin(),
                       water_to[water[i][j]].end());
  }
  return;
}

int main() {

  scanf("%d %d", &H, &W);

  water.resize(H * W);
  water_to.resize(H * W);
  isOne.resize(H * W, false);

  vector<pair<int, int>> order;

  int IndexCount = 0;
  rep(i, H) rep(j, W) {
    scanf("%d", &M[i][j]);
    order.push_back(make_pair(M[i][j], IndexCount));
    IndexCount++;
  }

  rep(i, H) rep(j, W) {
    rep(d, 4) {
      if (index(j + dx[d], i + dy[d]) != -1 &&
          M[i][j] > M[i + dy[d]][j + dx[d]]) {
        water[index(j, i)].push_back(index(j + dx[d], i + dy[d]));
      }
    }
  }

  sort(order.begin(), order.end());

  rep(i, order.size()) GetWaterTo(order[i].second);
  // rep(i, H*W) GetWaterTo(i);

  int c = 0;
  rep(i, H * W) if (isOne[i] || water_to[i].size() >= 2) c++;

  printf("%d\\n", c);

  return 0;
}