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

#include <cstdio>
#include <iostream>
#include <queue>

using namespace std;

#define f first
#define s second
#define mp make_pair

#define REP(i, n) for (int i = 0; i < (int)(n); i++)

int g[100][100];
bool memo[100][1000];

typedef pair<int, pair<int, int>> data;
inline data makedata(int a, int b, int c) {
  return make_pair(a, make_pair(b, c));
}
inline int elim(data d) { return d.f; }
inline int cost(data d) { return d.s.f; }
inline int pos(data d) { return d.s.s; }

int main() {
  int n, m, c;
  while (scanf("%d%d%d", &n, &m, &c), n + m + c) {
    REP(i, n) REP(j, n) g[i][j] = -1;
    REP(i, n) REP(j, m) memo[i][j] = false;

    REP(i, m) {
      int a, b, d;
      scanf("%d%d%d", &a, &b, &d);
      g[a - 1][b - 1] = d;
    }

    priority_queue<data, vector<data>, greater<data>> pq;
    pq.push(makedata(0, 0, 0));

    while (pq.size()) {
      data d = pq.top();
      pq.pop();
      int ee = elim(d);
      int cc = cost(d);
      int pp = pos(d);

      if (memo[pp][ee])
        continue;
      memo[pp][ee] = true;

      if (pp == n - 1 && cc <= c) {
        printf("%d\\n", ee);
        break;
      }

      REP(i, n) if (g[pp][i] >= 0) {
        if (!memo[i][ee + 1])
          pq.push(makedata(ee + 1, cc, i));
        if (!memo[i][ee])
          pq.push(makedata(ee, cc + g[pp][i], i));
      }
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

#define f first
#define s second
#define mp make_pair

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ALL(c) (c).begin(), (c).end()

using namespace std;

typedef unsigned int uint;
typedef long long ll;
typedef complex<double> P;

int minCost(const vector<vector<pair<int, int>>> &edge) {
  int n = edge.size();
  vector<bool> ok(n);
  vector<int> cost(n);

  typedef pair<int, int> data;
  priority_queue<data, vector<data>, greater<data>> pq;
  pq.push(mp(0, 0));

  while (pq.size()) {
    int pos = pq.top().s;
    int cos = pq.top().f;
    pq.pop();

    if (ok[pos])
      continue;
    ok[pos] = true;
    cost[pos] = cos;

    if (pos == n - 1)
      break;

    FOR(it, edge[pos]) {
      int next = it->f;
      if (!ok[next]) {
        int ncos = it->s + cos;
        pq.push(mp(ncos, next));
      }
    }
  }

  return cost[n - 1];
}

class Count {
  vector<int> memo;
  vector<int> cost;
  vector<vector<int>> e;

  set<pair<int, int>> &erased;
  const vector<vector<pair<int, int>>> &edge;
  int n;

public:
  Count(const vector<vector<pair<int, int>>> &ed, set<pair<int, int>> &er)
      : edge(ed), erased(er) {
    n = edge.size();
    e = vector<vector<int>>(n, vector<int>(n, -1));
    REP(i, n) REP(j, edge[i].size()) e[i][edge[i][j].f] = edge[i][j].s;
    memo = vector<int>(n, -1);
  }

  int iter(int pos) {
    if (pos == 0)
      return 0;
    if (memo[pos] != -1)
      return memo[pos];

    int ret = INT_MAX;
    REP(i, n) {
      if (e[i][pos] != -1) {
        if (cost[i] + e[i][pos] == cost[pos]) {
          if (erased.count(mp(i, pos)) == 0)
            ret = min(ret, iter(i));
          else
            ret = min(ret, iter(i) + 1);
        }
      }
    }

    return memo[pos] = ret;
  }

  int realAns() {
    vector<bool> ok(n);
    cost = vector<int>(n);

    typedef pair<int, int> data;
    priority_queue<data, vector<data>, greater<data>> pq;
    pq.push(mp(0, 0));

    while (pq.size()) {
      int pos = pq.top().s;
      int cos = pq.top().f;
      pq.pop();

      if (ok[pos])
        continue;
      ok[pos] = true;
      cost[pos] = cos;

      if (pos == n - 1)
        break;

      FOR(it, edge[pos]) {
        int next = it->f;
        if (!ok[next]) {
          int ncos = it->s + cos;
          pq.push(mp(ncos, next));
        }
      }
    }

    return iter(n - 1);
  }
};

int main() {
  int n, m, c;
  while (scanf("%d%d%d", &n, &m, &c), n + m + c) {
    vector<vector<pair<int, int>>> edge(n);
    set<pair<int, int>> erased;

    REP(i, m) {
      int s, d, cc;
      scanf("%d%d%d", &s, &d, &cc);
      edge[s - 1].push_back(make_pair(d - 1, cc));
    }

    int cost = INT_MAX;
    int cnt = 0;
    int ans = INT_MAX;

    while (cnt < n) {
      int si = 0, sj = 0;
      int minc = INT_MAX;

      REP(ii, n) REP(jj, edge[ii].size()) {
        int orgCost = edge[ii][jj].s;

        edge[ii][jj].s = 0;
        int tmpCost = minCost(edge);
        if (tmpCost < minc) {
          minc = tmpCost;
          si = ii;
          sj = jj;
        }

        edge[ii][jj].s = orgCost;
      }

      cost = minc;
      erased.insert(mp(si, edge[si][sj].f));
      edge[si][sj].s = 0;
      cnt++;
      if (minc <= c)
        ans = min(ans, Count(edge, erased).realAns());
    }

    printf("%d\\n", ans);
  }
  return 0;
}