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

#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>

using namespace std;

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

static const double EPS = 1e-8;

static const int tx[] = {0, 1, 0, -1};
static const int ty[] = {-1, 0, 1, 0};

struct State {
  int point;
  int total_cost;
  int cost2zero_times;
  State(int p) : point(p), total_cost(0), cost2zero_times(0) {}
  State(int p, int tc, int cz)
      : point(p), total_cost(tc), cost2zero_times(cz) {}
  bool operator<(const State &s) const {
    return cost2zero_times < s.cost2zero_times;
  }
  bool operator>(const State &s) const {
    return cost2zero_times > s.cost2zero_times;
  }
};

int dp[101][1001];

int bfs(const vector<P> edges[101], int num_of_nodes, int target_cost) {
  int res = INF;
  priority_queue<State, vector<State>, greater<State>> que;
  que.push(State(0));
  while (!que.empty()) {
    State s = que.top();
    if (s.point == num_of_nodes - 1 &&
        dp[s.point][s.cost2zero_times] < target_cost) {
      return s.cost2zero_times;
    }
    que.pop();
    for (int edge_i = 0; edge_i < edges[s.point].size(); edge_i++) {
      int next = edges[s.point][edge_i].first;
      int cost = edges[s.point][edge_i].second;
      if (dp[next][s.cost2zero_times] > s.total_cost + cost) {
        dp[next][s.cost2zero_times] = s.total_cost + cost;
        que.push(State(next, s.total_cost + cost, s.cost2zero_times));
      }
      if (dp[next][s.cost2zero_times + 1] > s.total_cost) {
        dp[next][s.cost2zero_times + 1] = s.total_cost;
        que.push(State(next, s.total_cost, s.cost2zero_times + 1));
      }
    }
  }
  return res;
}

int main() {
  int num_of_nodes;
  int num_of_edges;
  int target_cost;
  while (~scanf("%d %d %d", &num_of_nodes, &num_of_edges, &target_cost)) {
    if (num_of_nodes == 0 && num_of_edges == 0 && target_cost == 0) {
      break;
    }
    memset(dp, 0x3f, sizeof(dp));
    vector<P> edges[101];
    for (int edge_i = 0; edge_i < num_of_edges; edge_i++) {
      int src, dst, cost;
      scanf("%d %d %d", &src, &dst, &cost);
      src--;
      dst--;
      edges[src].push_back(P(dst, cost));
    }
    vector<int> current_cost;
    dp[0][0] = 0;
    printf("%d\\n", bfs(edges, num_of_nodes, target_cost));
  }
}

Error: TLE

Fixed submission:

#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>

using namespace std;

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

static const double EPS = 1e-8;

static const int tx[] = {0, 1, 0, -1};
static const int ty[] = {-1, 0, 1, 0};

struct State {
  int point;
  vector<int> cost_log;
  int total_cost;
  State(int p) : point(p), total_cost(0) {}
  State(int p, int tc, const vector<int> &cl)
      : point(p), total_cost(tc), cost_log(cl) {}
};

int dp[101][1001];

int dfs(const vector<P> edges[101], int num_of_nodes, int target_cost,
        int point, int count, int cost_sum, vector<int> &current_cost) {
  if (point == num_of_nodes - 1) {
    vector<int> tmp = current_cost;
    sort(tmp.begin(), tmp.end(), greater<int>());
    int sum = 0;
    for (int i = 0; i < tmp.size(); i++) {
      sum += tmp[i];
    }
    int ans = 0;
    for (int i = 0; i < tmp.size(); i++) {
      sum -= tmp[i];
      ans++;
      if (sum <= target_cost) {
        break;
      }
    }
    return ans;
  }

  int res = INF;
  for (int edge_i = 0; edge_i < edges[point].size(); edge_i++) {
    int next = edges[point][edge_i].first;
    int cost = edges[point][edge_i].second;
    if (dp[next][count + 1] <= cost_sum + cost)
      continue;

    current_cost.push_back(cost);
    dp[next][count + 1] = cost_sum + cost;
    res = min(res, dfs(edges, num_of_nodes, target_cost, next, count + 1,
                       cost_sum + cost, current_cost));
    current_cost.pop_back();
  }
  return res;
}

int bfs(const vector<P> edges[101], int num_of_nodes, int target_cost) {
  int res = INF;
  queue<State> que;
  que.push(State(0));
  while (!que.empty()) {
    State s = que.front();
    que.pop();
    for (int edge_i = 0; edge_i < edges[s.point].size(); edge_i++) {
      int next = edges[s.point][edge_i].first;
      int cost = edges[s.point][edge_i].second;
      vector<int> next_cost = s.cost_log;
      next_cost.push_back(cost);

      if (next == num_of_nodes - 1) {
        sort(next_cost.begin(), next_cost.end(), greater<int>());
        int sum = 0;
        for (int i = 0; i < next_cost.size(); i++) {
          sum += next_cost[i];
        }
        int ans = 0;
        for (int i = 0; i < next_cost.size(); i++) {
          sum -= next_cost[i];
          ans++;
          if (sum <= target_cost) {
            res = min(ans, res);
            break;
          }
        }
        continue;
      }

      if (dp[next][next_cost.size()] <= s.total_cost + cost)
        continue;
      dp[next][next_cost.size()] = s.total_cost + cost;
      que.push(State(next, s.total_cost + cost, next_cost));
    }
  }
  return res;
}

int main() {
  int num_of_nodes;
  int num_of_edges;
  int target_cost;
  while (~scanf("%d %d %d", &num_of_nodes, &num_of_edges, &target_cost)) {
    if (num_of_nodes == 0 && num_of_edges == 0 && target_cost == 0) {
      break;
    }
    memset(dp, 0x3f, sizeof(dp));
    vector<P> edges[101];
    for (int edge_i = 0; edge_i < num_of_edges; edge_i++) {
      int src, dst, cost;
      scanf("%d %d %d", &src, &dst, &cost);
      src--;
      dst--;
      edges[src].push_back(P(dst, cost));
    }
    vector<int> current_cost;
    dp[0][0] = 0;
    printf("%d\\n", bfs(edges, num_of_nodes, target_cost));
  }
}