Problem p01481 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

// common
#define BR "\n"

#define ALL(c) (c).begin(), (c).end()
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define EACH(it, o) for (auto it = (o).begin(); it != (o).end(); ++it)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))

typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pair<int, int>> vpii;
typedef long long ll;
typedef vector<long long> vl;
typedef pair<long long, long long> pll;
typedef vector<pair<long long, long long>> vpll;
typedef vector<string> vs;
typedef long double ld;

// debug
#ifdef NDEBUG
#define DUMP(x)
#define DUMPLN(x)
#define DEBUG(x)
#define DEBUGLN(x)
#define LINE()
#define LINELN()
#define CHECK(exp, act)
#define STOP(e)
#else
#define DUMP(x) cerr << #x << " = " << (x)
#define DUMPLN(x) DUMP(x) << endl
#define DEBUG(x) DUMP(x) << LINE() << " " << __FILE__
#define DEBUGLN(x) DEBUG(x) << endl
#define LINE() cerr << " (L" << __LINE__ << ")"
#define LINELN() LINE() << endl
#define CHECK(exp, act)                                                        \
  if (exp != act) {                                                            \
    DUMPLN(exp);                                                               \
    DEBUGLN(act);                                                              \
  }
#define STOP(e)                                                                \
  CHECK(e, true);                                                              \
  if (!(e))                                                                    \
    exit(1);
#endif

template <class T> inline string toString(const vector<T> &x) {
  stringstream ss;
  REP(i, x.size()) {
    if (i != 0)
      ss << " ";
    ss << x[i];
  }
  return ss.str();
}
template <class T> inline string toString(const vector<vector<T>> &map) {
  stringstream ss;
  REP(i, map.size()) {
    if (i != 0)
      ss << BR;
    ss << toString(map[i]);
  }
  return ss.str();
}
template <class K, class V> string toString(map<K, V> &x) {
  string res;
  stringstream ss;
  for (auto &p : x)
    ss << p.first << ":" << p.second << " ";
  return ss.str();
}

template <typename T, typename V> inline T mod(T v, V MOD) {
  return (v % MOD + MOD) % MOD;
}

struct UnionFind {
  vector<int> par;  // 親
  vector<int> rank; // 木の深さ
  int size;
  UnionFind(int n) {
    REP(i, n) par.push_back(i);
    rank = vector<int>(n);
    size = n;
  }
  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  bool same(int x, int y) { return root(x) == root(y); }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      par[x] = y;
    else
      par[y] = x;
    if (rank[x] == rank[y])
      rank[x]++;
    size--;
  }
};

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

int INF = 1 << 28;

int H, W;
int enc(int y, int x) { return y * W + x; }
int main() {
  cin >> H >> W;
  vector<string> map(H);
  REP(y, H) cin >> map[y];
  int N;
  cin >> N;
  vector<int> xs(N), ys(N);
  REP(i, N) cin >> xs[i] >> ys[i];

  int tx, ty;
  REP(y, H) REP(x, W) {
    if (map[y][x] == 't') {
      tx = x;
      ty = y;
    }
  }

  UnionFind uf(H * W);
  REP(y, H) REP(x, W) {
    if (map[y][x] == '#')
      continue;
    REP(di, 4) {
      int nx = x + dx[di], ny = y + dy[di];
      if (!IN(0, nx, W) || !IN(0, ny, H))
        continue;
      if (map[ny][nx] == '#')
        continue;
      uf.unite(enc(y, x), enc(ny, nx));
    }
  }

  int time = 0;
  while (!uf.same(enc(ty, tx), enc(0, 0))) {
    time++;
    if (time - 1 == N)
      break;
    int x = xs[time - 1], y = ys[time - 1];
    if (!IN(0, x, W) || !IN(0, y, H))
      continue;
    map[y][x] = '.';
    REP(di, 4) {
      int nx = x + dx[di], ny = y + dy[di];
      if (!IN(0, nx, W) || !IN(0, ny, H))
        continue;
      if (map[ny][nx] == '#')
        continue;
      uf.unite(enc(y, x), enc(ny, nx));
    }
  }
  cout << (time != N + 1 ? time : -1) << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

// common
#define BR "\n"

#define ALL(c) (c).begin(), (c).end()
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define EACH(it, o) for (auto it = (o).begin(); it != (o).end(); ++it)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))

typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pair<int, int>> vpii;
typedef long long ll;
typedef vector<long long> vl;
typedef pair<long long, long long> pll;
typedef vector<pair<long long, long long>> vpll;
typedef vector<string> vs;
typedef long double ld;

// debug
#ifdef NDEBUG
#define DUMP(x)
#define DUMPLN(x)
#define DEBUG(x)
#define DEBUGLN(x)
#define LINE()
#define LINELN()
#define CHECK(exp, act)
#define STOP(e)
#else
#define DUMP(x) cerr << #x << " = " << (x)
#define DUMPLN(x) DUMP(x) << endl
#define DEBUG(x) DUMP(x) << LINE() << " " << __FILE__
#define DEBUGLN(x) DEBUG(x) << endl
#define LINE() cerr << " (L" << __LINE__ << ")"
#define LINELN() LINE() << endl
#define CHECK(exp, act)                                                        \
  if (exp != act) {                                                            \
    DUMPLN(exp);                                                               \
    DEBUGLN(act);                                                              \
  }
#define STOP(e)                                                                \
  CHECK(e, true);                                                              \
  if (!(e))                                                                    \
    exit(1);
#endif

template <class T> inline string toString(const vector<T> &x) {
  stringstream ss;
  REP(i, x.size()) {
    if (i != 0)
      ss << " ";
    ss << x[i];
  }
  return ss.str();
}
template <class T> inline string toString(const vector<vector<T>> &map) {
  stringstream ss;
  REP(i, map.size()) {
    if (i != 0)
      ss << BR;
    ss << toString(map[i]);
  }
  return ss.str();
}
template <class K, class V> string toString(map<K, V> &x) {
  string res;
  stringstream ss;
  for (auto &p : x)
    ss << p.first << ":" << p.second << " ";
  return ss.str();
}

template <typename T, typename V> inline T mod(T v, V MOD) {
  return (v % MOD + MOD) % MOD;
}

struct UnionFind {
  vector<int> par;  // 親
  vector<int> rank; // 木の深さ
  int size;
  UnionFind(int n) {
    REP(i, n) par.push_back(i);
    rank = vector<int>(n);
    size = n;
  }
  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  bool same(int x, int y) { return root(x) == root(y); }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      par[x] = y;
    else
      par[y] = x;
    if (rank[x] == rank[y])
      rank[x]++;
    size--;
  }
};

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

int INF = 1 << 28;

int H, W;
int enc(int y, int x) { return y * W + x; }
int main() {
  cin >> W >> H;
  vector<string> map(H);
  REP(y, H) cin >> map[y];
  int N;
  cin >> N;
  vector<int> xs(N), ys(N);
  REP(i, N) cin >> xs[i] >> ys[i];

  int tx, ty;
  REP(y, H) REP(x, W) {
    if (map[y][x] == 't') {
      tx = x;
      ty = y;
    }
  }

  UnionFind uf(H * W);
  REP(y, H) REP(x, W) {
    if (map[y][x] == '#')
      continue;
    REP(di, 4) {
      int nx = x + dx[di], ny = y + dy[di];
      if (!IN(0, nx, W) || !IN(0, ny, H))
        continue;
      if (map[ny][nx] == '#')
        continue;
      uf.unite(enc(y, x), enc(ny, nx));
    }
  }

  int time = 0;
  while (!uf.same(enc(ty, tx), enc(0, 0))) {
    time++;
    if (time - 1 == N)
      break;
    int x = xs[time - 1], y = ys[time - 1];
    if (!IN(0, x, W) || !IN(0, y, H))
      continue;
    map[y][x] = '.';
    REP(di, 4) {
      int nx = x + dx[di], ny = y + dy[di];
      if (!IN(0, nx, W) || !IN(0, ny, H))
        continue;
      if (map[ny][nx] == '#')
        continue;
      uf.unite(enc(y, x), enc(ny, nx));
    }
  }
  cout << (time != N + 1 ? time : -1) << endl;
  return 0;
}