Problem p01481 (C++)

Buggy submission (status: Runtime Error):
#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;

const static int tx[] = {+0, +1, +0, -1};
const static int ty[] = {-1, +0, +1, +0};

static const double EPS = 1e-12;

int W, H;
char stage[1001][1001];
bool visited[1001][1001];

class State {
public:
  int x;
  int y;
  int cost;
  State(int _x, int _y, int _c) : x(_x), y(_y), cost(_c) {}

  bool operator<(const State &s) const { return cost < s.cost; }
  bool operator>(const State &s) const { return cost > s.cost; }
};

void bfs() {
  priority_queue<State, vector<State>, greater<State>> que;
  que.push(State(0, 0, 0));

  while (!que.empty()) {
    State s = que.top();
    que.pop();
    int sx = s.x;
    int sy = s.y;
    visited[sy][sx] = true;
    if (stage[sy][sx] == 't')
      break;
    for (int i = 0; i < 4; i++) {
      int dx = sx + tx[i];
      int dy = sy + ty[i];
      if (dx < 0 || dy < 0 || dx >= W || dy >= H)
        continue;
      if (visited[dy][dx])
        continue;
      if (stage[dy][dx] == '#')
        continue;
      que.push(State(dx, dy, s.cost + 1));
    }
  }
}

void dfs(int sx, int sy) {
  visited[sy][sx] = true;
  for (int i = 0; i < 4; i++) {
    int dx = sx + tx[i];
    int dy = sy + ty[i];
    if (dx < 0 || dy < 0 || dx >= W || dy >= H)
      continue;
    if (visited[dy][dx])
      continue;
    if (stage[dy][dx] == '#')
      continue;
    dfs(dx, dy);
  }
}

bool has_route(int time, const vector<P> &gates, int gx, int gy) {

  vector<P> skip;
  for (int i = 0; i < time; i++) {
    int x = gates[i].first;
    int y = gates[i].second;
    if (stage[y][x] == '.') {
      skip.push_back(gates[i]);
    }
    stage[y][x] = '.';
  }
  memset(visited, false, sizeof(visited));
  bfs();

  for (int i = 0; i < time; i++) {
    int x = gates[i].first;
    int y = gates[i].second;
    stage[y][x] = '#';
  }

  for (int i = 0; i < skip.size(); i++) {
    int x = skip[i].first;
    int y = skip[i].second;
    stage[y][x] = '.';
  }
  return visited[gy][gx];
}

int main() {

  while (~scanf("%d %d", &W, &H)) {

    int gx, gy;
    for (int y = 0; y < H; y++) {
      string line;
      cin >> line;
      for (int x = 0; x < W; x++) {
        stage[y][x] = line[x];
        if (line[x] == 't') {
          gx = x;
          gy = y;
        }
      }
    }

    vector<P> gates;
    int total_time;
    scanf("%d", &total_time);
    for (int time = 0; time < total_time; time++) {
      int x, y;
      scanf("%d %d", &x, &y);
      gates.push_back(P(x, y));
    }

    int min_time = 0;
    int max_time = gates.size();
    bool isok = false;
    for (int round = 0; round < 20; round++) {
      int mid = (min_time + max_time) / 2;
      if (has_route(mid, gates, gx, gy)) {
        max_time = mid;
        isok = true;
      } else {
        min_time = mid + 1;
      }
    }

    printf("%d\n", isok ? max_time : -1);
  }
}

Fixed submission:
#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;

const static int tx[] = {+0, +1, +0, -1};
const static int ty[] = {-1, +0, +1, +0};

static const double EPS = 1e-12;

int W, H;
char stage[1001][1001];
bool visited[1001][1001];

class State {
public:
  int x;
  int y;
  int cost;
  State(int _x, int _y, int _c) : x(_x), y(_y), cost(_c) {}

  bool operator<(const State &s) const { return cost < s.cost; }
  bool operator>(const State &s) const { return cost > s.cost; }
};

void bfs() {
  priority_queue<State, vector<State>, greater<State>> que;
  que.push(State(0, 0, 0));

  while (!que.empty()) {
    State s = que.top();
    que.pop();
    int sx = s.x;
    int sy = s.y;
    if (visited[sy][sx])
      continue;

    visited[sy][sx] = true;
    if (stage[sy][sx] == 't')
      break;
    for (int i = 0; i < 4; i++) {
      int dx = sx + tx[i];
      int dy = sy + ty[i];
      if (dx < 0 || dy < 0 || dx >= W || dy >= H)
        continue;
      if (visited[dy][dx])
        continue;
      if (stage[dy][dx] == '#')
        continue;
      que.push(State(dx, dy, s.cost + 1));
    }
  }
}

void dfs(int sx, int sy) {
  visited[sy][sx] = true;
  for (int i = 0; i < 4; i++) {
    int dx = sx + tx[i];
    int dy = sy + ty[i];
    if (dx < 0 || dy < 0 || dx >= W || dy >= H)
      continue;
    if (visited[dy][dx])
      continue;
    if (stage[dy][dx] == '#')
      continue;
    dfs(dx, dy);
  }
}

bool has_route(int time, const vector<P> &gates, int gx, int gy) {

  vector<P> skip;
  for (int i = 0; i < time; i++) {
    int x = gates[i].first;
    int y = gates[i].second;
    if (stage[y][x] == '.') {
      skip.push_back(gates[i]);
    }
    stage[y][x] = '.';
  }
  memset(visited, false, sizeof(visited));
  bfs();

  for (int i = 0; i < time; i++) {
    int x = gates[i].first;
    int y = gates[i].second;
    stage[y][x] = '#';
  }

  for (int i = 0; i < skip.size(); i++) {
    int x = skip[i].first;
    int y = skip[i].second;
    stage[y][x] = '.';
  }
  return visited[gy][gx];
}

int main() {

  while (~scanf("%d %d", &W, &H)) {

    int gx, gy;
    for (int y = 0; y < H; y++) {
      string line;
      cin >> line;
      for (int x = 0; x < W; x++) {
        stage[y][x] = line[x];
        if (line[x] == 't') {
          gx = x;
          gy = y;
        }
      }
    }

    vector<P> gates;
    int total_time;
    scanf("%d", &total_time);
    for (int time = 0; time < total_time; time++) {
      int x, y;
      scanf("%d %d", &x, &y);
      gates.push_back(P(x, y));
    }

    int min_time = 0;
    int max_time = gates.size();
    bool isok = false;
    for (int round = 0; round < 20; round++) {
      int mid = (min_time + max_time) / 2;
      if (has_route(mid, gates, gx, gy)) {
        max_time = mid;
        isok = true;
      } else {
        min_time = mid + 1;
      }
    }

    printf("%d\n", isok ? max_time : -1);
  }
}