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

// 単一始点最短経路 ( ダイクストラ法 : 優先度付きキュー )
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <stack>
#include <vector>

#include <queue>

using namespace std;

static const int MAX_N = 10000;
static const int INFTY = (1 << 21);
static const int WHITE = 0;
static const int GRAY = 1;
static const int BLACK = 2;

class q_element {
public:
  // 各頂点のNo.と経路の値
  int vertex_num;
  int vertex_val;

  // コンストラクタ
  q_element(int a, int b) {
    vertex_num = a;
    vertex_val = b;
  };
};

// ">" のオーバーロード [ receive_val ] を基準に大小比較を行う
bool operator>(const q_element &q_element_1, const q_element &q_element_2) {
  return q_element_1.vertex_val > q_element_2.vertex_val;
};

// q_elementクラスのオブジェクトを昇順にするためのキューの定義
std::priority_queue<q_element, std::vector<q_element>, std::greater<q_element>>
    pqEle;

// 隣接リストを作成する ( 頂点と重みの情報を格納する )
vector<q_element> v_Link[MAX_N + 1];

int n;

// ダイクストラ法を実施するメソッド( 優先度付きキュー )
int Dijkstra_priority_queue();

int main(void) {

  cin >> n;

  int k, c, u, v;
  q_element q_entity(0, 0);

  for (int i = 0; i < n; i++) {
    cin >> u >> k;

    for (int j = 0; j < k; j++) {
      cin >> v >> c;

      // 隣接リストの作成
      q_entity.vertex_num = v;
      q_entity.vertex_val = c;

      v_Link[u].push_back(q_entity);
    }
  }

  // 優先度付きキューを用いたダイクストラ法
  Dijkstra_priority_queue();

  return 0;
}

// 優先度付きキューを用いたダイクストラ法を実施するメソッド
int Dijkstra_priority_queue() {
  int u, v, minv;
  int d[MAX_N], p[MAX_N], color[MAX_N];

  for (int i = 0; i < n; i++) {
    d[i] = INFTY;
    p[i] = -1;
    color[i] = WHITE;
  }

  // 初期値の設定
  d[0] = 0;
  color[0] = GRAY;
  // キューに要素を入れる
  pqEle.push(q_element(0, 0));

  while (!pqEle.empty()) {
    // minv = INFTY;
    //  次に移動するべき頂点
    // u = -1;

    // 最小の値を持つ要素を取り出す ( キューの先頭 )
    u = pqEle.top().vertex_num;
    minv = pqEle.top().vertex_val;
    pqEle.pop();

    // 訪問完了
    color[u] = BLACK;

    for (int v_num = 0; v_num < v_Link[u].size(); v_num++) {
      // 隣接リストから要素を取得する
      v = v_Link[u][v_num].vertex_num;

      if (color[v] != BLACK) {
        // u → v の経路の中で, vのコストが最小のものが見つかれば更新する
        if (d[v] > d[u] + v_Link[u][v_num].vertex_val) {
          // コストの記録
          d[v] = d[u] + v_Link[u][v_num].vertex_val;
          // 頂点 v の親を記録する
          p[v] = u;
          // 訪問状態の記録
          color[v] = GRAY;

          // キューに要素を入れる
          pqEle.push(q_element(v, d[v]));
        }
      }
    }
  }

  // 結果の表示
  for (int i = 0; i < n; i++) {
    cout << i << " " << (d[i] == INFTY ? -1 : d[i]) << endl;
  }

  return 0;
}


Error: MLE

Fixed submission:

// 単一始点最短経路 ( ダイクストラ法 : 優先度付きキュー )
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <stack>
#include <vector>

#include <queue>

using namespace std;

static const int MAX_N = 10000;
static const int INFTY = (1 << 21);
static const int WHITE = 0;
static const int GRAY = 1;
static const int BLACK = 2;

class q_element {
public:
  // 各頂点のNo.と経路の値
  int vertex_num;
  int vertex_val;

  // コンストラクタ
  q_element(int a, int b) {
    vertex_num = a;
    vertex_val = b;
  };
};

// ">" のオーバーロード [ receive_val ] を基準に大小比較を行う
bool operator>(const q_element &q_element_1, const q_element &q_element_2) {
  return q_element_1.vertex_val > q_element_2.vertex_val;
};

// q_elementクラスのオブジェクトを昇順にするためのキューの定義
std::priority_queue<q_element, std::vector<q_element>, std::greater<q_element>>
    pqEle;

// 隣接リストを作成する
vector<int> v_Link[MAX_N + 1];

int n, M[MAX_N][MAX_N];

// ダイクストラ法を実施するメソッド( 優先度付きキュー )
int Dijkstra_priority_queue();

int main(void) {

  cin >> n;

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      // 配列の初期化
      M[i][j] = INFTY;
    }
  }

  int k, c, u, v;

  for (int i = 0; i < n; i++) {
    cin >> u >> k;

    for (int j = 0; j < k; j++) {
      cin >> v >> c;

      // 隣接リストの作成
      v_Link[u].push_back(v);
      // 辺の値の代入
      M[u][v] = c;
    }
  }

  // 優先度付きキューを用いたダイクストラ法
  Dijkstra_priority_queue();

  return 0;
}

// 優先度付きキューを用いたダイクストラ法を実施するメソッド
int Dijkstra_priority_queue() {
  int u, v, minv;
  int d[MAX_N], p[MAX_N], color[MAX_N];

  for (int i = 0; i < n; i++) {
    d[i] = INFTY;
    p[i] = -1;
    color[i] = WHITE;
  }

  // 初期値の設定
  d[0] = 0;
  color[0] = GRAY;
  // キューに要素を入れる
  pqEle.push(q_element(0, 0));

  while (!pqEle.empty()) {
    // minv = INFTY;
    //  次に移動するべき頂点
    // u = -1;

    // 最小の値を持つ要素を取り出す ( キューの先頭 )
    u = pqEle.top().vertex_num;
    minv = pqEle.top().vertex_val;
    pqEle.pop();

    // 訪問完了
    color[u] = BLACK;

    for (int v_num = 0; v_num < v_Link[u].size(); v_num++) {
      // 隣接リストから要素を取得する
      v = v_Link[u][v_num];

      if (color[v] != BLACK) {
        // u → v の経路の中で, vのコストが最小のものが見つかれば更新する
        if (d[v] > d[u] + M[u][v]) {
          // コストの記録
          d[v] = d[u] + M[u][v];
          // 頂点 v の親を記録する
          p[v] = u;
          // 訪問状態の記録
          color[v] = GRAY;

          // キューに要素を入れる
          pqEle.push(q_element(v, d[v]));
        }
      }
    }
  }

  // 結果の表示
  for (int i = 0; i < n; i++) {
    cout << i << " " << (d[i] == INFTY ? -1 : d[i]) << endl;
  }

  return 0;
}