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

// {{{ include
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
// }}}

using namespace std;

typedef long long ll;
inline int in() {
  int x;
  scanf("%d", &x);
  return x;
}

const int INF = 1 << 29;

struct Edge {
  int from, to;
  int cost;
  int hp;
  Edge(int from, int to, int cost, int hp)
      : from(from), to(to), cost(cost), hp(hp) {}
  bool operator<(const Edge &e) const { return cost > e.cost; }
};

typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

int main() {
  int N, M, L, K, A, H;
  while (cin >> N >> M >> L >> K >> A >> H, N) {
    Graph G(N);
    int cold[110] = {};
    int vis[110][110] = {};
    int dist[110][110];
    for (int i = 0; i < N; i++)
      fill_n(dist[i], M + 1, INF);
    for (int i = 0; i < L; i++) {
      int X;
      cin >> X;
      cold[X] = 1;
    }
    for (int i = 0; i < K; i++) {
      int X, Y, T;
      cin >> X >> Y >> T;
      G[X].push_back(Edge(X, Y, T, 0));
      G[Y].push_back(Edge(Y, X, T, 0));
    }
    priority_queue<Edge> pq;
    for (pq.push(Edge(-1, A, 0, M)); !pq.empty(); pq.pop()) {
      Edge e = pq.top();
      if (vis[e.to][e.hp]++)
        continue;
      if (cold[e.to]) {
        for (auto &v : G[e.to]) {
          for (int i = max(e.hp, v.cost); i <= M; i++) {
            int ncost = e.cost + v.cost + (i - e.hp);
            int nhp = i - v.cost;
            if (dist[v.to][nhp] <= ncost)
              continue;
            dist[v.to][nhp] = ncost;
            pq.push(Edge(e.to, v.to, ncost, nhp));
          }
        }
      } else {
        for (auto &v : G[e.to]) {
          if (e.hp < v.cost)
            continue;
          if (e.cost + v.cost >= dist[v.to][e.hp - v.cost])
            continue;
          dist[v.to][e.hp - v.cost] = e.cost + v.cost;
          pq.push(Edge(e.to, v.to, e.cost + v.cost, e.hp - v.cost));
        }
      }
    }
    int cost = *min_element(dist[H], dist[H] + M + 1);
    if (cost == INF)
      puts("Help!");
    else
      printf("%d\\n", cost);
  }

  return 0;
}

Error: TLE

Fixed submission:

// {{{ include
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
// }}}

using namespace std;

typedef long long ll;
inline int in() {
  int x;
  scanf("%d", &x);
  return x;
}

const int INF = 1 << 29;

struct Edge {
  int from, to;
  int cost;
  int hp;
  Edge(int from, int to, int cost, int hp)
      : from(from), to(to), cost(cost), hp(hp) {}
  bool operator<(const Edge &e) const { return cost > e.cost; }
};

typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

int main() {
  int N, M, L, K, A, H;
  while (cin >> N >> M >> L >> K >> A >> H, N) {
    Graph G(N);
    int cold[110] = {};
    int vis[110][110] = {};
    int dist[110];
    fill_n(dist, N, INF);

    for (int i = 0; i < L; i++) {
      int X;
      cin >> X;
      cold[X] = 1;
    }
    for (int i = 0; i < K; i++) {
      int X, Y, T;
      cin >> X >> Y >> T;
      G[X].push_back(Edge(X, Y, T, 0));
      G[Y].push_back(Edge(Y, X, T, 0));
    }
    priority_queue<Edge> pq;
    for (pq.push(Edge(-1, A, 0, M)); !pq.empty(); pq.pop()) {
      Edge e = pq.top();
      if (vis[e.to][e.hp]++)
        continue;
      dist[e.to] = min(dist[e.to], e.cost);
      if (e.to == H)
        break;
      if (cold[e.to]) {
        for (auto &v : G[e.to]) {
          for (int i = max(e.hp, v.cost); i <= M; i++) {
            pq.push(Edge(e.to, v.to, e.cost + v.cost + (i - e.hp), i - v.cost));
          }
        }
      } else {
        for (auto &v : G[e.to]) {
          if (e.hp < v.cost)
            continue;
          pq.push(Edge(e.to, v.to, e.cost + v.cost, e.hp - v.cost));
        }
      }
    }
    if (dist[H] == INF)
      puts("Help!");
    else
      printf("%d\\n", dist[H]);
  }

  return 0;
}