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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_W = 50;
const int MAX_H = 50;
const int MAX_HW = MAX_H * MAX_W;
const int MAX_N = 1000;

const int INF = 1 << 29;

const int dxs[] = {1, 0, -1, 0}, dys[] = {0, 1, 0, -1};

/* typedef */

typedef pair<int, int> pii;
typedef vector<pii> vpii;

/* global variables */

int w, h, n, hw;
int ipos, opos;
int nbrs[MAX_HW][4];
int dists[MAX_HW], prvs[MAX_HW];
vpii cwls;

/* subroutines */

int min_dist() {
  for (int i = 0; i < hw; i++)
    dists[i] = INF;
  dists[ipos] = 0;
  prvs[ipos] = -1;

  queue<int> q;
  q.push(ipos);

  while (!q.empty()) {
    int u = q.front();
    q.pop();
    if (u == opos)
      break;

    for (int di = 0; di < 4; di++) {
      int v = nbrs[u][di];
      if (v >= 0 && dists[v] >= INF) {
        dists[v] = dists[u] + 1;
        q.push(v);
        prvs[v] = u;
      }
    }
  }

  return dists[opos];
}

/* main */

int main() {
  cin >> w >> h >> n;
  hw = h * w;

  int dpos[] = {1, w, -1, -w};

  for (int y = 0, pos = 0; y < h; y++)
    for (int x = 0; x < w; x++, pos++)
      for (int di = 0; di < 4; di++) {
        int x0 = x + dxs[di], y0 = y + dys[di], pos0 = pos + dpos[di];
        nbrs[pos][di] = (x0 >= 0 && x0 < w && y0 >= 0 && y0 < h) ? pos0 : -1;
      }

  for (int i = 0; i < n; i++) {
    int sx, sy, dx, dy;
    cin >> sx >> sy >> dx >> dy;

    if (sy == dy) {
      if (sx > dx)
        swap(sx, dx);
      if (sy > 0)
        for (int x = sx; x < dx; x++)
          nbrs[(sy - 1) * w + x][1] = -1;
      if (sy < h)
        for (int x = sx; x < dx; x++)
          nbrs[sy * w + x][3] = -1;
    } else {
      if (sy > dy)
        swap(sy, dy);
      if (sx > 0)
        for (int y = sy; y < dy; y++)
          nbrs[y * w + sx - 1][0] = -1;
      if (sx < w)
        for (int y = sy; y < dy; y++)
          nbrs[y * w + sx][2] = -1;
    }
  }

  for (int pos = 0; false && pos < hw; pos++) {
    printf("nbrs[%d] =", pos);
    for (int di = 0; di < 4; di++)
      printf(" %d", nbrs[pos][di]);
    putchar('\\n');
  }

  int ix, iy, ox, oy;
  cin >> ix >> iy;
  cin >> ox >> oy;

  ipos = iy * w + ix;
  opos = oy * w + ox;
  // printf("ipos=%d, opos=%d\\n", ipos, opos);

  int mind = min_dist();
  // printf("mind=%d\\n", mind);

  for (int pos = opos; prvs[pos] != -1; pos = prvs[pos]) {
    cwls.push_back(pii(pos, prvs[pos]));
    // printf("%d->%d\\n", pos, prvs[pos]);
  }

  int max_diff = 0;

  for (vpii::iterator vit = cwls.begin(); vit != cwls.end(); vit++) {
    int p0 = vit->first, p1 = vit->second;
    int d0, d1;

    for (d0 = 0; d0 < 4 && nbrs[p0][d0] != p1; d0++)
      ;
    d1 = (d0 + 2) % 4;

    nbrs[p0][d0] = nbrs[p1][d1] = -1;

    int mind0 = min_dist();
    // if (mind0 < INF) printf("mind0=%d\\n", mind0);

    nbrs[p0][d0] = p1;
    nbrs[p1][d1] = p0;

    if (mind0 < INF && max_diff < mind0 - mind)
      max_diff = mind0 - mind;
  }

  cout << max_diff << endl;

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_W = 50;
const int MAX_H = 50;
const int MAX_HW = MAX_H * MAX_W;
const int MAX_N = 1000;

const int INF = 1 << 29;

const int dxs[] = {1, 0, -1, 0}, dys[] = {0, 1, 0, -1};

/* typedef */

typedef pair<int, int> pii;
typedef vector<pii> vpii;

/* global variables */

int w, h, n, hw;
int ipos, opos;
int nbrs[MAX_N][4];
int dists[MAX_N], prvs[MAX_N];
vpii cwls;

/* subroutines */

int min_dist() {
  for (int i = 0; i < hw; i++)
    dists[i] = INF;
  dists[ipos] = 0;
  prvs[ipos] = -1;

  queue<int> q;
  q.push(ipos);

  while (!q.empty()) {
    int u = q.front();
    q.pop();
    if (u == opos)
      break;

    for (int di = 0; di < 4; di++) {
      int v = nbrs[u][di];
      if (v >= 0 && dists[v] >= INF) {
        dists[v] = dists[u] + 1;
        q.push(v);
        prvs[v] = u;
      }
    }
  }

  return dists[opos];
}

/* main */

int main() {
  cin >> w >> h >> n;
  hw = h * w;

  int dpos[] = {1, w, -1, -w};

  for (int y = 0, pos = 0; y < h; y++)
    for (int x = 0; x < w; x++, pos++)
      for (int di = 0; di < 4; di++) {
        int x0 = x + dxs[di], y0 = y + dys[di], pos0 = pos + dpos[di];
        nbrs[pos][di] = (x0 >= 0 && x0 < w && y0 >= 0 && y0 < h) ? pos0 : -1;
      }

  for (int i = 0; i < n; i++) {
    int sx, sy, dx, dy;
    cin >> sx >> sy >> dx >> dy;

    if (sy == dy) {
      if (sy > 0)
        for (int x = sx; x < dx; x++)
          nbrs[(sy - 1) * w + x][1] = -1;
      if (sy < h)
        for (int x = sx; x < dx; x++)
          nbrs[sy * w + x][3] = -1;
    } else {
      if (sx > 0)
        for (int y = sy; y < dy; y++)
          nbrs[y * w + sx - 1][0] = -1;
      if (sx < w)
        for (int y = sy; y < dy; y++)
          nbrs[y * w + sx][2] = -1;
    }
  }

  for (int pos = 0; false && pos < hw; pos++) {
    printf("nbrs[%d] =", pos);
    for (int di = 0; di < 4; di++)
      printf(" %d", nbrs[pos][di]);
    putchar('\\n');
  }

  int ix, iy, ox, oy;
  cin >> ix >> iy;
  cin >> ox >> oy;

  ipos = iy * w + ix;
  opos = oy * w + ox;
  // printf("ipos=%d, opos=%d\\n", ipos, opos);

  int mind = min_dist();
  // cout << mind << endl;

  for (int pos = opos; prvs[pos] != -1; pos = prvs[pos]) {
    cwls.push_back(pii(pos, prvs[pos]));
    // printf("%d->%d\\n", pos, prvs[pos]);
  }

  int max_diff = 0;

  for (vpii::iterator vit = cwls.begin(); vit != cwls.end(); vit++) {
    int p0 = vit->first, p1 = vit->second;
    int d0, d1;

    if (p0 + 1 == p1)
      d0 = 0, d1 = 2;
    else if (p0 + w == p1)
      d0 = 1, d1 = 3;
    else if (p0 - 1 == p1)
      d0 = 2, d1 = 0;
    else
      d0 = 3, d1 = 1;

    nbrs[p0][d0] = nbrs[p1][d1] = -1;

    int mind0 = min_dist();

    nbrs[p0][d0] = p1;
    nbrs[p1][d1] = p0;

    if (mind0 < INF && max_diff < mind0 - mind)
      max_diff = mind0 - mind;
  }

  cout << max_diff << endl;

  return 0;
}