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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

#define rep(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define all(v) (v).begin(), (v).end()
#define rev(s) (s).rbegin(), (s).rend()
#define MP make_pair
#define X first
#define Y second

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

void fin() { freopen("test.txt", "r", stdin); }

struct state {
  int freeze;
  int total;
  int pos;
  state(int f = 0, int t = 0, int p = 0) {
    freeze = f;
    total = t;
    pos = p;
  }
  bool operator<(const state &rhs) const {
    if (total == rhs.total)
      return freeze < rhs.freeze;
    return total > rhs.total;
  }
};

const int INF = 1 << 29;

int main() {
  // fin();
  while (1) {
    int n, m, l, k, a, h;
    cin >> n >> m >> l >> k >> a >> h;
    if (!n)
      break;
    vector<int> hasf(n, 0);
    rep(i, l) {
      int f;
      cin >> f;
      hasf[f] = 1;
    }
    vector<vector<int>> edge(n, vector<int>(n, INF));
    rep(i, k) {
      int x, y, t;
      cin >> x >> y >> t;
      edge[x][y] = edge[y][x] = t;
    }

    priority_queue<state> q;
    q.push(state(m, 0, a));

    vector<vector<int>> cost(m + 1, vector<int>(n, INF));
    vector<int> visit(n, 0);
    while (!q.empty()) {
      state s = q.top();
      q.pop();

      if (cost[s.freeze][s.pos] <= s.total)
        continue;
      cost[s.freeze][s.pos] = s.total;
      if (s.pos == h)
        break;

      if (!visit[s.pos]) {
        if (hasf[s.pos]) {
          for (int j = 1; j <= m - s.freeze; j++) {
            state next = s;
            next.freeze += j;
            next.total += j;
            q.push(next);
          }
        }
      }
      visit[s.pos] = true;

      rep(i, n) {
        if (edge[s.pos][i] == INF)
          continue;
        state next = s;
        next.freeze -= edge[s.pos][i];
        if (next.freeze < 0)
          continue;
        next.pos = i;
        next.total += edge[s.pos][i];
        q.push(next);
      }
    }

    int best = INF;
    rep(i, m) { best = min(best, cost[i][h]); }

    if (best == INF)
      cout << "Help!" << endl;
    else
      cout << best << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

#define rep(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define all(v) (v).begin(), (v).end()
#define rev(s) (s).rbegin(), (s).rend()
#define MP make_pair
#define X first
#define Y second

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

void fin() { freopen("test.txt", "r", stdin); }

struct state {
  int freeze;
  int total;
  int pos;
  state(int f = 0, int t = 0, int p = 0) {
    freeze = f;
    total = t;
    pos = p;
  }
  bool operator<(const state &rhs) const {
    if (total == rhs.total)
      return freeze < rhs.freeze;
    return total > rhs.total;
  }
};

const int INF = 1 << 29;

int main() {
  // fin();
  while (1) {
    int n, m, l, k, a, h;
    cin >> n >> m >> l >> k >> a >> h;
    if (!n)
      break;
    vector<int> hasf(n, 0);
    rep(i, l) {
      int f;
      cin >> f;
      hasf[f] = 1;
    }
    vector<vector<int>> edge(n, vector<int>(n, INF));
    rep(i, k) {
      int x, y, t;
      cin >> x >> y >> t;
      edge[x][y] = edge[y][x] = t;
    }

    priority_queue<state> q;
    q.push(state(m, 0, a));

    vector<vector<int>> cost(m + 1, vector<int>(n, INF));
    while (!q.empty()) {
      state s = q.top();
      q.pop();

      if (cost[s.freeze][s.pos] <= s.total)
        continue;
      cost[s.freeze][s.pos] = s.total;
      if (s.pos == h)
        break;

      if (hasf[s.pos]) {
        for (int j = 1; j <= m - s.freeze; j++) {
          state next = s;
          next.freeze += j;
          next.total += j;
          q.push(next);
        }
      }

      rep(i, n) {
        if (edge[s.pos][i] == INF)
          continue;
        state next = s;
        next.freeze -= edge[s.pos][i];
        if (next.freeze < 0)
          continue;
        next.pos = i;
        next.total += edge[s.pos][i];
        q.push(next);
      }
    }

    int best = INF;
    rep(i, m) { best = min(best, cost[i][h]); }

    if (best == INF)
      cout << "help!" << endl;
    else
      cout << best << endl;
  }

  return 0;
}