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

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

typedef pair<int, int> pii;
struct Situation {
public:
  pii cost;
  int node;
  int rev;
  Situation(pii cost_, int node_, int rev_) {
    cost = cost_;
    node = node_;
    rev = rev_;
  }
  Situation();
  bool operator<(const Situation &s) const { return s.cost < this->cost; }
};

const int INF = 1000000000;
const int MAX_V = 1001;

vector<int> G[MAX_V];
vector<int> revG[MAX_V];
pii d[MAX_V][2];
int EdgeNum[MAX_V][MAX_V];
pii prevv[MAX_V][2];
void dijkstra(int s) {
  priority_queue<Situation> que;
  for (int i = 0; i < MAX_V; i++) {
    for (int j = 0; j < 2; j++) {
      d[i][j].first = INF;
      d[i][j].second = 0;
      prevv[i][j].first = prevv[i][j].second = -1;
    }
  }
  d[s][0].first = 0;
  que.push(Situation(pii(0, 0), s, 0));
  while (que.size()) {
    Situation p = que.top();
    que.pop();
    int node = p.node;
    pii cost = p.cost;
    int rev = p.rev;
    if (d[node][rev] < cost)
      continue;
    for (int i = 0; i < G[node].size(); i++) {
      int to = G[node][i];
      if (d[to][rev].first > d[node][rev].first + 1) {
        d[to][rev].first = d[node][rev].first + 1;
        d[to][rev].second = d[node][rev].second;
        que.push(Situation(d[to][rev], to, rev));
        prevv[to][rev] = pii(node, rev);
      }
      // 一致する場合
      else if (d[to][rev].first == d[node][rev].first + 1) {
        if (d[to][rev].second > d[node][rev].second) {
          d[to][rev].second = d[node][rev].second;
          que.push(Situation(d[to][rev], to, rev));
          prevv[to][rev] = pii(node, rev);
        }
      }
    }
    if (!rev) {
      for (int i = 0; i < revG[node].size(); i++) {
        int to = revG[node][i];
        if (d[to][rev ^ 1].first > d[node][rev].first + 1) {
          d[to][rev ^ 1].first = d[node][rev].first + 1;
          d[to][rev ^ 1].second = EdgeNum[to][node];
          que.push(Situation(d[to][rev ^ 1], to, rev ^ 1));
          prevv[to][rev ^ 1] = pii(node, rev);
        } else if (d[to][rev ^ 1].first == d[node][rev].first + 1) {
          if (d[to][rev ^ 1].second > EdgeNum[to][node]) {
            d[to][rev ^ 1].second = EdgeNum[to][node];
            que.push(Situation(d[to][rev ^ 1], to, rev));
            prevv[to][rev ^ 1] = pii(node, rev);
          }
        }
      }
    }
  }
}

int N, M;
int S, T;
int main() {

  while (cin >> N && N) {
    for (int i = 0; i < N; i++) {
      G[i].clear();
      revG[i].clear();
    }
    cin >> S >> T;
    S--;
    T--;
    cin >> M;
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++)
        EdgeNum[i][j] = INF;
    for (int i = 0; i < M; i++) {
      int a, b;
      cin >> a >> b;
      a--;
      b--;
      G[a].push_back(b);
      revG[b].push_back(a);
      EdgeNum[a][b] = min(EdgeNum[a][b], i + 1);
      EdgeNum[b][a] = min(EdgeNum[b][a], i + 1);
    }
    dijkstra(S);
    pii res = min(d[T][0], d[T][1]);
    cout << res.first << " " << res.second << endl;
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

typedef pair<int, int> pii;
struct Situation {
public:
  int cost;
  int node;
  int rev;
  Situation(int cost_, int node_, int rev_) {
    cost = cost_;
    node = node_;
    rev = rev_;
  }
  Situation();
  bool operator<(const Situation &s) const { return s.cost < this->cost; }
};

const int INF = 1000000000;
const int MAX_V = 1001;

vector<int> G[MAX_V];
vector<int> revG[MAX_V];
int d[MAX_V][2];
int EdgeNum[MAX_V][MAX_V];
pii prevv[MAX_V][2];
int rvs[MAX_V][2];
void dijkstra(int s) {
  priority_queue<Situation> que;
  for (int i = 0; i < MAX_V; i++) {
    for (int j = 0; j < 2; j++) {
      d[i][j] = INF;
      prevv[i][j].first = prevv[i][j].second = -1;
      rvs[i][j] = -1;
    }
  }
  d[s][0] = 0;
  que.push(Situation(0, s, 0));
  while (que.size()) {
    Situation p = que.top();
    que.pop();
    int node = p.node;
    int cost = p.cost;
    int rev = p.rev;
    if (d[node][rev] < cost)
      continue;
    for (int i = 0; i < G[node].size(); i++) {
      int to = G[node][i];
      if (d[to][rev] >= d[node][rev] + 1) {
        d[to][rev] = d[node][rev] + 1;
        que.push(Situation(d[to][rev], to, rev));
        prevv[to][rev] = pii(node, rev);
      }
    }
    if (!rev) {
      for (int i = 0; i < revG[node].size(); i++) {
        int to = revG[node][i];
        if (d[to][rev ^ 1] >= d[node][rev] + 1 &&
            (rvs[to][rev ^ 1] == -1 || rvs[to][rev ^ 1] > EdgeNum[to][node])) {
          d[to][rev ^ 1] = d[node][rev] + 1;
          que.push(Situation(d[to][rev ^ 1], to, rev ^ 1));
          prevv[to][rev ^ 1] = pii(node, rev);
          rvs[to][rev ^ 1] = EdgeNum[to][node];
        }
      }
    }
  }
}

int N, M;
int S, T;
int main() {

  while (cin >> N && N) {
    for (int i = 0; i < N; i++) {
      G[i].clear();
      revG[i].clear();
    }
    cin >> S >> T;
    S--;
    T--;
    cin >> M;
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++)
        EdgeNum[i][j] = INF;
    for (int i = 0; i < M; i++) {
      int a, b;
      cin >> a >> b;
      a--;
      b--;
      G[a].push_back(b);
      revG[b].push_back(a);
      EdgeNum[a][b] = min(EdgeNum[a][b], i + 1);
      EdgeNum[b][a] = min(EdgeNum[b][a], i + 1);
    }
    dijkstra(S);
    int res = min(d[T][0], d[T][1]);
    int change = 0;
    if (d[T][0] > d[T][1]) {
      pii cur;
      cur.first = T;
      cur.second = 1;
      while (cur.first != -1) {
        pii nxt = prevv[cur.first][cur.second];
        if (nxt.second != cur.second) {
          change = rvs[cur.first][cur.second];
          break;
        }
        cur = nxt;
      }
    }
    cout << res << " " << change << endl;
  }

  return 0;
}