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

#include <functional>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int n, k;
int c[5000], r[5000];
int a[10000], b[10000];
vector<int> et[5000];   //???????????°??????
bool table[5000][5000]; //??°????????°??????

void input() {
  cin >> n >> k;
  for (int i = 0; i < n; i++)
    cin >> c[i] >> r[i];
  for (int i = 0; i < k; i++) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
  }
  for (int i = 0; i < k; i++) {
    et[a[i]].push_back(b[i]);
    et[b[i]].push_back(a[i]);
  }
}

void bfs(int start) {
  queue<int> que;
  int minCost[5000], i;

  for (i = 0; i < n; i++)
    minCost[i] = 114514;
  minCost[start] = 0;
  que.push(start);

  while (!que.empty()) {
    int v = que.front();
    que.pop();
    for (int i = 0; i < et[v].size(); i++) {
      if (minCost[et[v][i]] > minCost[v] + 1) {
        minCost[et[v][i]] = minCost[v] + 1;
        que.push(et[v][i]);
      }
    }
  }
  for (i = 0; i < n; i++)
    table[start][i] = (minCost[i] <= r[start]);
}

int dijkstra() {
  int minCost[5000], i;
  bool updated[5000];

  for (i = 0; i < n; i++) {
    minCost[i] = 1145141919;
    updated[i] = false;
  }
  minCost[0] = 0;

  while (true) {
    int id = -1;
    for (i = 0; i < n; i++) {
      if (updated[i])
        continue;
      if (id == -1 || minCost[id] > minCost[i]) {
        id = i;
      }
    }
    if (id == -1) {
      break;
    }

    updated[id] = true;
    for (i = 0; i < n; i++) {
      if (table[id][i] && minCost[i] > minCost[id] + c[id]) {
        minCost[i] = minCost[id] + c[id];
      }
    }
  }
  return minCost[n - 1];
}

int main() {
  input();
  for (int i = 0; i < n; i++)
    bfs(i);
  cout << dijkstra() << endl;
  return 0;
}

Error: TLE

Fixed submission:

// 最安値が更新されたら経路を考え直すと、探索回数が増えてしまう。
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

typedef priority_queue<int> PQ;

struct Node {
  int len;             // 行ける距離
  vector<int> edge_to; // 行けるノード(動的配列)
  int edge_cost;       // そのノードからのコスト
  bool done;           // コストの最小値が確定したか
  int cost;            // 今の最小コスト
};
Node node[5000];
int lastest[5000];

void makeN(int num, int maxdepth, int depth) {
  if (maxdepth < depth)
    return;
  vector<int>::iterator it = node[num].edge_to.begin();
  while (it != node[num].edge_to.end()) {
    int t = *it;
    if (lastest[t] == 0) {
      lastest[t] = 1;
      makeN(t, maxdepth, depth + 1);
    }
    it++;
  }
}
int main() {
  int i, j, N, K;
  cin >> N >> K;
  for (i = 0; i < N; i++) {
    cin >> node[i].edge_cost >> node[i].len;
    node[i].cost = -1;
    node[i].done = false;
  }
  int a, b;
  for (i = 0; i < K; i++) {
    cin >> a >> b;
    a--;
    b--;
    node[a].edge_to.push_back(b);
    node[b].edge_to.push_back(a);
  }
  for (i = 0; i < N; i++) {
    lastest[i] = 1;
    makeN(i, node[i].len, 1);
    for (j = 0; j < N; j++) {
      if (j == i)
        continue;
      if (lastest[j]) {
        node[i].edge_to.push_back(j);
        lastest[j] = 0;
      }
    }
    lastest[i] = 0;
  }
  // 探索(なんとなくわかるが、いまいち証明できないDijkstra法を実装)
  vector<int> start; // 調べるノード
  int now_edge, min_edge;
  vector<int>::iterator it, minit;
  node[0].cost = 0;
  start.push_back(0);
  while (node[N - 1].done == false) {
    // 頂点の確定(今から調べるノードのうち最小コストのもの)
    it = start.begin();
    while (node[*it].done && it != start.end()) {
      it++;
    }
    if (it == start.end())
      break;
    min_edge = *it;
    while (it != start.end()) {
      now_edge = *it;
      if (node[now_edge].done)
        continue;
      if (node[min_edge].cost > node[now_edge].cost) {
        min_edge = now_edge;
        minit = it;
      }
      it++;
    }
    /*デバック
    for(i = 0;i < N;i++){
            cout << node[i].cost << " ";
    }
    cout << endl;*/
    node[min_edge].done = true;
    // 確定した頂点から枝を伸ばす(すると、この確定頂点経由でのコストは最小となる)
    it = node[min_edge].edge_to.begin();
    while (it != node[min_edge].edge_to.end()) {
      if (node[*it].done) {
        it++;
        continue;
      }
      if (node[*it].cost == -1 ||
          node[*it].cost > node[min_edge].cost + node[min_edge].edge_cost) {
        if (node[*it].cost == -1)
          start.push_back(*it);
        node[*it].cost = node[min_edge].cost + node[min_edge].edge_cost;
      }
      it++;
    }
  }
  cout << node[N - 1].cost << endl;
  return 0;
}