Problem p00200 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
#define INF 1000000000 // INF=∞
using namespace std;
typedef pair<int, int> P; // firstは最短距離,secondは頂点番号

const int MAX_M = 100;

struct edge {
  int to, cost;
  // edge() : to(0), cost(0) {}
  // edge(int to, int cost) : to(to), cost(cost) {}
};
int V; // 頂点の数

vector<vector<edge>> time_graph(MAX_M); // 頂点間の距離情報(隣接リスト)
vector<vector<edge>> cost_graph(MAX_M);

vector<vector<int>> time_ds(MAX_M);
vector<vector<int>> cost_ds(MAX_M);

int dijkstra_time(int s, int g) {
  if (!time_ds[s].empty())
    return time_ds[s][g];

  priority_queue<P, vector<P>, greater<P>> que;
  vector<int> d(V, INF); // 最短距離を記録する配列(∞で初期化しておく)
  d[s] = 0;              // 頂点sから頂点sへの最短距離は0で確定
  que.push(P(0, s)); // 距離0,頂点sからスタート

  while (!que.empty()) {
    /*処理1*/
    // キューの中で最も頂点sからの距離が近い頂点vとその距離cを取得
    P p = que.top();
    que.pop();
    int v = p.second, c = p.first;

    /*処理2*/
    // 頂点vの最短距離がすでに確定していたらcontenue
    if (d[v] < c)
      continue;

    /*処理3*/
    // 頂点vの最短距離が既に確定していなければ頂点vへの最短経路はcで確定
    d[v] = c;

    /*処理4*/
    // 頂点vから移動しうる頂点とその距離をキューに入れる
    for (int i = 0; i < time_graph[v].size(); i++) {
      // 頂点vはG[v].size()個の行き先を持つ
      edge e = time_graph[v][i];
      if (d[e.to] > d[v] + e.cost) {
        que.push(P(d[v] + e.cost, e.to));
      }
    }
  }
  time_ds[s] = d;
  return d[g]; // 頂点gへの最短距離を返す
}

int dijkstra_cost(int s, int g) {
  if (!cost_ds[s].empty())
    return cost_ds[s][g];

  priority_queue<P, vector<P>, greater<P>> que;
  vector<int> d(V, INF); // 最短距離を記録する配列(∞で初期化しておく)
  d[s] = 0;              // 頂点sから頂点sへの最短距離は0で確定
  que.push(P(0, s)); // 距離0,頂点sからスタート

  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second, c = p.first;

    if (d[v] < c)
      continue;

    d[v] = c;

    for (int i = 0; i < cost_graph[v].size(); i++) {
      edge e = cost_graph[v][i];
      if (d[e.to] > d[v] + e.cost) {
        que.push(P(d[v] + e.cost, e.to));
      }
    }
  }

  cost_ds[s] = d;
  return d[g]; // 頂点gへの最短距離を返す
}

int main() {
  int n, m;
  while (cin >> n >> m, n || m) {
    V = m;

    for (int i = 0; i < MAX_M; i++) {
      time_graph[i].clear();
      time_ds[i].clear();
      cost_graph[i].clear();
      cost_ds[i].clear();
    }

    for (int i = 0; i < n; i++) {
      int a, b, time, cost;
      cin >> a >> b >> time >> cost;
      a--;
      b--; // 0-indexedにする
      edge e1, e2, e3, e4;
      e1.to = e3.to = b;
      e1.cost = e2.cost = time;
      e2.to = e4.to = a;
      e3.cost = e4.cost = cost;
      time_graph[a].push_back(e1);
      time_graph[b].push_back(e2);
      cost_graph[a].push_back(e3);
      cost_graph[b].push_back(e4);
    }

    int k;
    cin >> k;
    for (int i = 0; i < k; i++) {
      int p, q, r;
      cin >> p >> q >> r;
      p--;
      q--;
      if (p > q)
        swap(p, q);
      if (r == 0)
        cout << dijkstra_time(p, q) << endl;
      else
        cout << dijkstra_cost(p, q) << endl;
    }
  }
}

Error: TLE

Fixed submission:

#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
#define INF 1000000000 // INF=∞
using namespace std;
typedef pair<int, int> P; // firstは最短距離,secondは頂点番号

const int MAX_M = 100;

struct edge {
  int to, cost;
  // edge() : to(0), cost(0) {}
  // edge(int to, int cost) : to(to), cost(cost) {}
};
int V; // 頂点の数

vector<vector<edge>> time_graph(MAX_M); // 頂点間の距離情報(隣接リスト)
vector<vector<edge>> cost_graph(MAX_M);

int dijkstra_time(int s, int g) {
  priority_queue<P, vector<P>, greater<P>> que;
  vector<int> d(V, INF); // 最短距離を記録する配列(∞で初期化しておく)
  d[s] = 0;              // 頂点sから頂点sへの最短距離は0で確定
  que.push(P(0, s)); // 距離0,頂点sからスタート

  while (!que.empty()) {
    /*処理1*/
    // キューの中で最も頂点sからの距離が近い頂点vとその距離cを取得
    P p = que.top();
    que.pop();
    int v = p.second, c = p.first;

    /*処理2*/
    // 頂点vの最短距離がすでに確定していたらcontenue
    if (d[v] < c)
      continue;

    /*処理3*/
    // 頂点vの最短距離が既に確定していなければ頂点vへの最短経路はcで確定
    d[v] = c;

    /*処理4*/
    // 頂点vから移動しうる頂点とその距離をキューに入れる
    for (int i = 0; i < time_graph[v].size(); i++) {
      // 頂点vはG[v].size()個の行き先を持つ
      edge e = time_graph[v][i];
      if (d[e.to] > d[v] + e.cost) {
        que.push(P(d[v] + e.cost, e.to));
      }
    }
  }

  return d[g]; // 頂点gへの最短距離を返す
}

int dijkstra_cost(int s, int g) {
  priority_queue<P, vector<P>, greater<P>> que;
  vector<int> d(V, INF); // 最短距離を記録する配列(∞で初期化しておく)
  d[s] = 0;              // 頂点sから頂点sへの最短距離は0で確定
  que.push(P(0, s)); // 距離0,頂点sからスタート

  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second, c = p.first;

    if (d[v] < c)
      continue;

    d[v] = c;

    for (int i = 0; i < cost_graph[v].size(); i++) {
      edge e = cost_graph[v][i];
      if (d[e.to] > d[v] + e.cost) {
        que.push(P(d[v] + e.cost, e.to));
      }
    }
  }

  return d[g]; // 頂点gへの最短距離を返す
}

int main() {
  int n, m;
  while (cin >> n >> m, n || m) {
    V = m;

    for (int i = 0; i < MAX_M; i++) {
      time_graph[i].clear();
      cost_graph[i].clear();
    }

    for (int i = 0; i < n; i++) {
      int a, b, time, cost;
      cin >> a >> b >> time >> cost;
      a--;
      b--; // 0-indexedにする
      edge e1, e2, e3, e4;
      e1.to = e3.to = b;
      e1.cost = e2.cost = time;
      e2.to = e4.to = a;
      e3.cost = e4.cost = cost;
      time_graph[a].push_back(e1);
      time_graph[b].push_back(e2);
      cost_graph[a].push_back(e3);
      cost_graph[b].push_back(e4);
    }

    int k;
    cin >> k;
    for (int i = 0; i < k; i++) {
      int p, q, r;
      cin >> p >> q >> r;
      p--;
      q--;
      if (r == 0)
        cout << dijkstra_time(p, q) << endl;
      else
        cout << dijkstra_cost(p, q) << endl;
    }
  }
}