Problem p01481 (C++)

Buggy submission (status: Runtime Error):
#include <iostream>
#include <stack>
using namespace std;

// union_find begin
#define MAX 500000
struct node {
  int parent, size;
};
node tree[MAX];
void init() {
  for (int i = 0; i < MAX; i++) {
    tree[i].parent = i;
    tree[i].size = 1;
  }
}
/*
int find(int x){
  if(tree[x].parent==x)return x;
  tree[x].parent = find( tree[x].parent );
  return tree[x].parent;
}
*/
int find(int x) {
  stack<int> st;
  while (tree[x].parent != x) {
    st.push(x);
    x = tree[x].parent;
  }
  while (!st.empty()) {
    tree[st.top()].parent = x;
    st.pop();
  }
  return x;
}

int count(int x) {
  x = find(x);
  return tree[x].size;
}

bool same(int x, int y) { return (find(x) == find(y)); }

void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y)
    return;
  if (count(x) > count(y))
    swap(x, y);
  tree[x].parent = y;
  tree[y].size += tree[x].size;
}
// union find end

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

int W, H, N, target;
char t[1005][1005];

int change(int i, int j) { return i * W + j; }

int solve() {
  cin >> N;
  for (int ans = 1; ans <= N; ans++) {
    int i, j;
    cin >> j >> i;
    if (t[i][j] == '.')
      continue;
    t[i][j] = '.';
    for (int k = 0; k < 4; k++) {
      int ni = i + dy[k];
      int nj = j + dx[k];
      if (ni < 0 || nj < 0 || H <= ni || W <= nj)
        continue;
      if (t[ni][nj] == '#')
        continue;
      unite(change(i, j), change(ni, nj));
    }
    if (same(target, 0))
      return ans;
  }
  return -1;
}

int main() {
  init();
  cin >> W >> H;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> t[i][j];
      if (t[i][j] == 't')
        target = change(i, j);
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (t[i][j] == '#')
        continue;
      for (int k = 0; k < 4; k++) {
        int ni = i + dy[k];
        int nj = j + dx[k];
        if (ni < 0 || nj < 0 || H <= ni || W <= nj)
          continue;
        if (t[ni][nj] == '#')
          continue;
        unite(change(i, j), change(ni, nj));
      }
    }
  }
  if (same(target, 0)) {
    cout << "0" << endl;
  } else {
    cout << solve() << endl;
  }
  return 0;
}

Fixed submission:
#include <iostream>
#include <stack>
using namespace std;

// union_find begin
#define MAX 5000000
struct node {
  int parent, size;
};
node tree[MAX];
void init() {
  for (int i = 0; i < MAX; i++) {
    tree[i].parent = i;
    tree[i].size = 1;
  }
}
/*
int find(int x){
  if(tree[x].parent==x)return x;
  tree[x].parent = find( tree[x].parent );
  return tree[x].parent;
}
*/
int find(int x) {
  stack<int> st;
  while (tree[x].parent != x) {
    st.push(x);
    x = tree[x].parent;
  }
  while (!st.empty()) {
    tree[st.top()].parent = x;
    st.pop();
  }
  return x;
}

int count(int x) {
  x = find(x);
  return tree[x].size;
}

bool same(int x, int y) { return (find(x) == find(y)); }

void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y)
    return;
  if (count(x) > count(y))
    swap(x, y);
  tree[x].parent = y;
  tree[y].size += tree[x].size;
}
// union find end

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

int W, H, N, target;
char t[1005][1005];

int change(int i, int j) { return i * W + j; }

int solve() {
  cin >> N;
  for (int ans = 1; ans <= N; ans++) {
    int i, j;
    cin >> j >> i;
    if (t[i][j] == '.')
      continue;
    t[i][j] = '.';
    for (int k = 0; k < 4; k++) {
      int ni = i + dy[k];
      int nj = j + dx[k];
      if (ni < 0 || nj < 0 || H <= ni || W <= nj)
        continue;
      if (t[ni][nj] == '#')
        continue;
      unite(change(i, j), change(ni, nj));
    }
    if (same(target, 0))
      return ans;
  }
  return -1;
}

int main() {
  init();
  cin >> W >> H;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> t[i][j];
      if (t[i][j] == 't')
        target = change(i, j);
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (t[i][j] == '#')
        continue;
      for (int k = 0; k < 4; k++) {
        int ni = i + dy[k];
        int nj = j + dx[k];
        if (ni < 0 || nj < 0 || H <= ni || W <= nj)
          continue;
        if (t[ni][nj] == '#')
          continue;
        unite(change(i, j), change(ni, nj));
      }
    }
  }
  if (same(target, 0)) {
    cout << "0" << endl;
  } else {
    cout << solve() << endl;
  }
  return 0;
}