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

#include <bits/stdc++.h>

using namespace std;

const int INF = 1001001001;

struct Edge {
  int to, cost;
  Edge() {}
  Edge(int to, int cost) : to(to), cost(cost) {}
};

struct State {
  Edge e;
  int ltime;
  State(Edge e, int ltime) : e(e), ltime(ltime) {}
  bool operator>(const State &rhs) const { return (e.cost > rhs.e.cost); }
};

int main() {
  int N, M, L, K, A, H;

  while (scanf("%d %d %d %d %d %d", &N, &M, &L, &K, &A, &H) && N) {
    vector<Edge> G[128];
    bool able[128] = {0};
    int dp[128][128];

    for (int i = 0; i < N; i++) {
      fill(dp[i], dp[i] + 128, INF);
    }

    for (int i = 0; i < L; i++) {
      int x;
      scanf("%d", &x);
      able[x] = true;
    }
    able[A] = able[H] = 0;

    for (int i = 0; i < K; i++) {
      int a, b, c;
      scanf("%d %d %d", &a, &b, &c);
      G[a].push_back(Edge(b, c));
      G[b].push_back(Edge(a, c));
    }

    priority_queue<State, vector<State>, greater<State>> pq;
    pq.push(State(Edge(A, 0), M));

    while (!pq.empty()) {
      State tmp = pq.top();
      pq.pop();
      if (dp[tmp.e.to][tmp.ltime] <= tmp.e.cost)
        continue;
      dp[tmp.e.to][tmp.ltime] = tmp.e.cost;

      if (tmp.e.to == H)
        break;

      for (int i = 0; i < G[tmp.e.to].size(); i++) {
        Edge nxt = G[tmp.e.to][i];
        if (nxt.cost > tmp.ltime)
          continue;
        for (int j = 0; j + tmp.ltime - nxt.cost <= M; j++) {
          if (j != 0 && !able[nxt.to])
            break;
          else if (dp[nxt.to][j + tmp.ltime - nxt.cost] >=
                   tmp.e.cost + j + nxt.cost) {
            pq.push(State(Edge(nxt.to, tmp.e.cost + j + nxt.cost),
                          j + tmp.ltime - nxt.cost));
          }
        }
      }
    }

    int ans = *min_element(dp[H], dp[H] + M + 1);
    if (ans != INF)
      printf("%d\\n", ans);
    else
      printf("Help!\\n");
  }

  return (0);
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

const int INF = 1001001001;

struct Edge {
  int to, cost;
  Edge() {}
  Edge(int to, int cost) : to(to), cost(cost) {}
};

struct State {
  Edge e;
  int ltime;
  State(Edge e, int ltime) : e(e), ltime(ltime) {}
  bool operator>(const State &rhs) const { return (e.cost > rhs.e.cost); }
};

int main() {
  int N, M, L, K, A, H;

  while (scanf("%d %d %d %d %d %d", &N, &M, &L, &K, &A, &H) && N) {
    vector<Edge> G[128];
    bool able[128] = {0};
    int dp[128][128];

    for (int i = 0; i < N; i++) {
      fill(dp[i], dp[i] + 128, INF);
    }

    for (int i = 0; i < L; i++) {
      int x;
      scanf("%d", &x);
      able[x] = true;
    }
    able[A] = able[H] = 0;

    for (int i = 0; i < K; i++) {
      int a, b, c;
      scanf("%d %d %d", &a, &b, &c);
      G[a].push_back(Edge(b, c));
      G[b].push_back(Edge(a, c));
    }

    priority_queue<State, vector<State>, greater<State>> pq;
    pq.push(State(Edge(A, 0), M));

    while (!pq.empty()) {
      State tmp = pq.top();
      pq.pop();
      if (dp[tmp.e.to][tmp.ltime] <= tmp.e.cost)
        continue;
      dp[tmp.e.to][tmp.ltime] = tmp.e.cost;

      for (int i = 0; i < G[tmp.e.to].size(); i++) {
        Edge nxt = G[tmp.e.to][i];
        if (nxt.cost > tmp.ltime)
          continue;
        for (int j = 0; j + tmp.ltime - nxt.cost <= M; j++) {
          if (j != 0 && !able[nxt.to])
            break;
          else if (dp[nxt.to][j + tmp.ltime - nxt.cost] >=
                   tmp.e.cost + j + nxt.cost) {
            pq.push(State(Edge(nxt.to, tmp.e.cost + j + nxt.cost),
                          j + tmp.ltime - nxt.cost));
          }
        }
      }
    }

    int ans = *min_element(dp[H], dp[H] + M + 1);
    if (ans != INF)
      printf("%d\\n", ans);
    else
      printf("Help!\\n");
  }

  return (0);
}