Problem p01208 (C++) — buggy submission, verdict: Memory Limit Exceeded

#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_M = 1000;
const int INF = 1 << 30;

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

/* typedef */

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

struct ISect {
  int i, x, y;
  int nbrs[4], ds[4];
};

struct Stat {
  int d, i, di;
  Stat(){};
  Stat(int _d, int _i, int _di) : d(_d), i(_i), di(_di){};
  bool operator>(const Stat &s0) const { return d > s0.d; }
  void print() { printf("Stat:d=%d, i=%d, di=%d\\n", d, i, di); }
};

/* global variables */

int m, n;
ISect isects[MAX_M];
map<string, int> nmhash;
int dists[MAX_M][4], npis[MAX_M][4];

/* subroutines */

/* main */

int main() {
  for (;;) {
    cin >> m >> n;
    if (m == 0)
      break;

    nmhash.clear();

    for (int i = 0; i < m; i++) {
      string name;
      cin >> name >> isects[i].x >> isects[i].y;
      isects[i].i = i;
      nmhash[name] = i;
      for (int j = 0; j < 4; j++)
        isects[i].nbrs[j] = -1, isects[i].ds[j] = 0;
    }

    for (int i = 0; i < n; i++) {
      string nm0, nm1;
      cin >> nm0 >> nm1;
      ISect *is0 = &isects[nmhash[nm0]];
      ISect *is1 = &isects[nmhash[nm1]];

      int dx = is1->x - is0->x;
      int dy = is1->y - is0->y;

      if (dx != 0) {
        if (dx > 0) {
          is0->nbrs[0] = is1->i;
          is1->nbrs[2] = is0->i;
          is0->ds[0] = is1->ds[2] = dx;
        } else {
          is0->nbrs[2] = is1->i;
          is1->nbrs[0] = is0->i;
          is0->ds[2] = is1->ds[0] = -dx;
        }
      } else {
        if (dy > 0) {
          is0->nbrs[1] = is1->i;
          is1->nbrs[3] = is0->i;
          is0->ds[1] = is1->ds[3] = dy;
        } else {
          is0->nbrs[3] = is1->i;
          is1->nbrs[1] = is0->i;
          is0->ds[3] = is1->ds[1] = -dy;
        }
      }
    }

    string stnm, glnm;
    cin >> stnm >> glnm;

    int st = nmhash[stnm];
    int gl = nmhash[glnm];
    // printf("st=%d, gl=%d\\n", st, gl);

    priority_queue<Stat, vector<Stat>, greater<Stat>> q;

    for (int di = 0; di < 4; di++) {
      for (int i = 0; i < m; i++)
        dists[i][di] = INF;
      dists[st][di] = 0;
      npis[st][di] = 1;
      q.push(Stat(0, st, di));
    }

    int min_dist = INF;
    int min_npi = 0;

    while (!q.empty()) {
      Stat u = q.top();
      q.pop();
      // u.print();

      if (u.d != dists[u.i][u.di])
        continue;
      if (u.i == gl) {
        if (min_dist > u.d) {
          min_dist = u.d;
          min_npi = npis[u.i][u.di];
        } else if (min_dist == u.d && min_npi > npis[u.i][u.di])
          min_npi = npis[u.i][u.di];
        continue;
      }

      ISect &isu = isects[u.i];
      for (int di = 0; di < 2; di++) {
        int vdi = (u.di + di) & 3;
        int vi = isu.nbrs[vdi];
        if (vi >= 0) {
          int vd = u.d + isu.ds[vdi];
          int vnpi = npis[u.i][u.di] + 1;
          if (dists[vi][vdi] > vd) {
            dists[vi][vdi] = vd;
            npis[vi][vdi] = vnpi;
            q.push(Stat(vd, vi, vdi));
          } else if (dists[vi][vdi] == vd && npis[vi][vdi] > vnpi) {
            npis[vi][vdi] = vnpi;
            q.push(Stat(vd, vi, vdi));
          }
        }
      }
    }

    if (min_dist >= INF)
      cout << "impossible" << endl;
    else
      cout << min_npi << endl;
  }

  return 0;
}

Error: MLE

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_M = 1000;
const int INF = 1 << 30;

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

/* typedef */

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

struct ISect {
  int i, x, y;
  int nbrs[4], ds[4];
};

struct Stat {
  int d, i, di;
  Stat(){};
  Stat(int _d, int _i, int _di) : d(_d), i(_i), di(_di){};
  bool operator>(const Stat &s0) const { return d > s0.d; }
};

/* global variables */

int m, n;
ISect isects[MAX_M];
map<string, ISect *> nmhash;
int dists[MAX_M][4], npis[MAX_M][4];

/* subroutines */

/* main */

int main() {
  for (;;) {
    cin >> m >> n;
    if (m == 0)
      break;

    nmhash.clear();

    for (int i = 0; i < m; i++) {
      string name;
      cin >> name >> isects[i].x >> isects[i].y;
      isects[i].i = i;
      nmhash[name] = &isects[i];
      for (int j = 0; j < 4; j++)
        isects[i].nbrs[j] = -1, isects[i].ds[j] = 0;
    }

    for (int i = 0; i < n; i++) {
      string nm0, nm1;
      cin >> nm0 >> nm1;
      ISect *is0 = nmhash[nm0];
      ISect *is1 = nmhash[nm1];

      int dx = is1->x - is0->x;
      int dy = is1->y - is0->y;

      if (dy == 0) {
        if (dx > 0) {
          is0->nbrs[0] = is1->i;
          is0->ds[0] = dx;
          is1->nbrs[2] = is0->i;
          is1->ds[2] = -dx;
        } else {
          is0->nbrs[2] = is1->i;
          is0->ds[2] = -dx;
          is1->nbrs[0] = is0->i;
          is1->ds[0] = dx;
        }
      } else {
        if (dy > 0) {
          is0->nbrs[1] = is1->i;
          is0->ds[1] = dy;
          is1->nbrs[3] = is0->i;
          is1->ds[3] = -dy;
        } else {
          is0->nbrs[3] = is1->i;
          is0->ds[3] = -dy;
          is1->nbrs[1] = is0->i;
          is1->ds[1] = dy;
        }
      }
    }

    string stnm, glnm;
    cin >> stnm >> glnm;

    int st = nmhash[stnm]->i;
    int gl = nmhash[glnm]->i;

    for (int di = 0; di < 4; di++) {
      for (int i = 0; i < m; i++)
        dists[i][di] = INF;
      dists[st][di] = 0;
      npis[st][di] = 1;
    }

    priority_queue<Stat, vector<Stat>, greater<Stat>> q;
    for (int di = 0; di < 4; di++)
      q.push(Stat(0, st, di));

    int min_dist = INF;
    int min_npi = 0;

    while (!q.empty()) {
      Stat u = q.top();
      q.pop();

      if (u.d != dists[u.i][u.di])
        continue;
      if (u.i == gl) {
        min_dist = u.d;
        min_npi = npis[u.i][u.di];
      }

      ISect &isu = isects[u.i];
      for (int di = 0; di < 2; di++) {
        int vdi = (u.di + di) & 3;
        int vi = isu.nbrs[vdi];
        if (vi >= 0) {
          int vd = u.d + isu.ds[vdi];
          if (dists[vi][vdi] > vd) {
            dists[vi][vdi] = vd;
            npis[vi][vdi] = npis[u.i][u.di] + 1;
            q.push(Stat(vd, vi, vdi));
          }
        }
      }
    }

    if (min_dist >= INF)
      cout << "impossible" << endl;
    else
      cout << min_npi << endl;
  }

  return 0;
}