Problem p01107 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>

using namespace std;

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

int N, M;
int inNode[NMAX * NMAX], outNode[NMAX * NMAX];
char grid[NMAX][NMAX];

struct FlowEdge {
  int x, y, flow, capacity;
  FlowEdge *rev;
  FlowEdge(int x, int y, int flow, int capacity, FlowEdge *rev = NULL)
      : x(x), y(y), flow(flow), capacity(capacity), rev(rev) {}
};
vector<FlowEdge *> FN[4 * NMAX * NMAX];

void addFlowEdge(int x, int y, int capacity) {
  FlowEdge *newEdge = new FlowEdge(x, y, 0, capacity);
  FlowEdge *revEdge = new FlowEdge(y, x, 0, 0, newEdge);
  newEdge->rev = revEdge;
  FN[x].push_back(newEdge);
  FN[y].push_back(revEdge);
}

bool bfsWitness[4 * NMAX * NMAX];
FlowEdge *from[4 * NMAX * NMAX];
bool hasAugumentingPath(int source, int sink) {
  memset(bfsWitness, 0, sizeof bfsWitness);
  queue<int> Q;
  Q.push(source);
  bfsWitness[source] = 1;
  from[source] = 0;
  while (!Q.empty()) {
    int now = Q.front();
    Q.pop();
    for (auto it : FN[now]) {
      if (bfsWitness[it->y] || it->flow >= it->capacity)
        continue;
      bfsWitness[it->y] = 1;
      from[it->y] = it;
      Q.push(it->y);
      if (it->y == sink)
        goto _breakLoop;
    }
  }
_breakLoop:
  return bfsWitness[sink];
}

int main() {
  //	assert(freopen("debug.in", "r", stdin));
  // assert(freopen("debug.out", "w", stdout));

  int i, j;

  cin >> N >> M;
  while (N != 0 || M != 0) {
    for (i = 1; i <= N; ++i)
      cin >> (grid[i] + 1);

    int lastNode = N * M + 1;
    for (i = 1; i <= N; ++i) {
      for (j = 1; j <= M; ++j) {
        inNode[(i - 1) * M + j] = lastNode++;
        outNode[(i - 1) * M + j] = lastNode++;
        addFlowEdge(inNode[(i - 1) * M + j], (i - 1) * M + j, 1);
        addFlowEdge((i - 1) * M + j, outNode[(i - 1) * M + j], 1);
      }
    }

    for (i = 1; i <= N; ++i) {
      for (j = 1; j <= M; ++j) {
        for (int d = 0; d < 4; ++d) {
          int newX = i + dx[d];
          int newY = j + dy[d];
          if (newX < 0 || newX > N || newY < 0 || newY > M ||
              grid[newX][newY] != '.')
            continue;
          addFlowEdge(outNode[(i - 1) * M + j], inNode[(newX - 1) * M + newY],
                      1);
        }
      }
    }

    FN[1][1]->capacity = 2;
    FN[inNode[1]][0]->capacity = 0;
    FN[N * M][1]->capacity = 0;
    FN[inNode[N * M]][0]->capacity = 2;

    int maxFlow = 0;
    while (hasAugumentingPath(1, N * M)) {
      FlowEdge *currEdge = from[N * M];
      while (currEdge) {
        ++currEdge->flow;
        --currEdge->rev->flow;
        currEdge = from[currEdge->x];
      }
      ++maxFlow;
    }

    if (maxFlow < 2) {
      cout << "NO\\n";
      goto _continue;
    }

    for (i = 1; i < lastNode; ++i)
      for (auto it : FN[i])
        it->flow = 0;

    FN[1][1]->capacity = 1;
    FN[inNode[1]][0]->capacity = 1;
    FN[N * M][1]->capacity = 1;
    FN[inNode[N * M]][0]->capacity = 1;

    FN[(N - 1) * M + 1][1]->capacity = 2;
    FN[inNode[(N - 1) * M + 1]][0]->capacity = 0;
    FN[M][1]->capacity = 0;
    FN[inNode[M]][0]->capacity = 2;

    maxFlow = 0;
    while (hasAugumentingPath((N - 1) * M + 1, M)) {
      FlowEdge *currEdge = from[M];
      while (currEdge) {
        ++currEdge->flow;
        --currEdge->rev->flow;
        currEdge = from[currEdge->x];
      }
      ++maxFlow;
    }

    if (maxFlow < 2)
      cout << "NO\\n";
    else
      cout << "YES\\n";

  _continue:
    for (i = 1; i < lastNode; ++i)
      for (auto it : FN[i])
        delete it;
    for (i = 1; i < lastNode; ++i)
      FN[i].clear();
    cin >> N >> M;
  }

  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

int n, m, dir, x, y;
char s[55][55];
bool uz[55][55];

struct rol {
  int x, y, dir;
};
vector<rol> R;

void bordare() {
  for (int i = 1; i <= n; i++)
    uz[i][m + 1] = uz[i][0] = 1;
  for (int i = 1; i <= m; i++)
    uz[n + 1][i] = uz[0][i] = 1;
}

bool OK(int x, int y) {
  if (uz[x][y] == 1 || s[x][y] == '#')
    return 0;
  return 1;
}

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

int main() {
  while (cin >> n >> m) {
    if (n == 0 && m == 0)
      return 0;
    memset(uz, 0, sizeof(uz));
    for (int i = 1; i <= n; i++) {
      cin >> s[i] + 1;
    }
    bordare();
    x = y = 1;
    int nr1 = 0, nr2 = 0, nr3 = 0;
    dir = 0;
    R.clear();
    R.push_back({x, y, dir});
    while (true) {
      int ok = 0;
      for (int k = 0; k < 4; k++) {
        int aux = (k + dir) % 4;
        if (OK(x + dx[aux], y + dy[aux])) {
          dir = (aux - 1 + 4) % 4;
          ok = 1;
          x += dx[aux];
          y += dy[aux];
          break;
        }
      }
      uz[x][y] = 1;
      if (!ok) {
        if (!R.empty()) {
          if (x == n && y == m)
            nr1 = 0;
          if (x == 1 && y == m)
            nr2 = 0;
          if (x == n && y == 1)
            nr3 = 0;
          R.pop_back();
          x = R.back().x;
          y = R.back().y;
          dir = R.back().dir;
          continue;
        }
        cout << "NO\\n";
        break;
      }
      R.push_back({x, y, dir});
      if (x == n && y == m)
        nr1 = 1;
      if (x == 1 && y == m)
        nr2 = 1;
      if (x == n && y == 1)
        nr3 = 1;
      if (x == 1 && y == 1) {
        if (nr1 + nr2 + nr3 == 3) {
          cout << "YES\\n";
          break;
        } else {
          cout << "NO\\n";
          break;
        }
      }
    }
  }
  return 0;
}

/*
5 7
....#..
..#.#..
..###..
.......
.......
*/