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

#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <stdio.h>
#include <vector>
typedef long long int ll;

#define BIG_NUM 2000000000

using namespace std;

struct Node {

  Node(int arg_to, int arg_cost, bool isUsed) {
    to = arg_to;
    cost = arg_cost;
    used = isUsed;
  }
  bool operator<(const struct Node &arg) const { return cost > arg.cost; };

  int to, cost;
  bool used;
};

void func(int N, int M) {

  vector<Node> V[N + 1], workV[N + 1];

  int from, to, cost, D_used[N + 1], D_unused[N + 1];

  for (int i = 1; i <= N; i++) {
    D_used[i] = BIG_NUM;
    D_unused[i] = BIG_NUM;
  }

  D_used[1] = 0;
  D_unused[1] = 0;

  for (int loop = 0; loop < M; loop++) {
    scanf("%d %d %d", &from, &to, &cost);

    V[from].push_back(Node(to, cost, false));
    V[to].push_back(Node(from, cost, false));
  }

  int middle;

  for (int i = 1; i <= N; i++) {
    for (int k = 0; k < V[i].size(); k++) {
      middle = V[i][k].to;
      for (int p = 0; p < V[middle].size(); p++) {
        if (i != V[middle][p].to) {
          workV[i].push_back(Node(V[middle][p].to, 0, true));
        }
      }
    }
  }

  for (int i = 1; i <= N; i++) {
    for (int k = 0; k < workV[i].size(); k++) {
      V[i].push_back(workV[i][k]);
    }
  }

  priority_queue<Node> Q;

  for (int i = 0; i < V[1].size(); i++) {
    if (V[1][i].used == false) {
      D_unused[V[1][i].to] = V[1][i].cost;
    } else {
      D_used[V[1][i].to] = V[1][i].cost;
    }
    Q.push(Node(V[1][i].to, V[1][i].cost, V[1][i].used));
  }

  int min_index;
  while (!Q.empty()) {
    if (Q.top().used == true) {
      if (Q.top().cost == D_used[Q.top().to]) {
        min_index = Q.top().to;
        Q.pop();
      } else {
        Q.pop();
        continue;
      }

      for (int k = 0; k < V[min_index].size(); k++) {
        if (V[min_index][k].used == false) {
          if (D_used[V[min_index][k].to] >
              D_used[min_index] + V[min_index][k].cost) {
            D_used[V[min_index][k].to] =
                D_used[min_index] + V[min_index][k].cost;
            Q.push(Node(V[min_index][k].to, D_used[V[min_index][k].to], true));
          }
        } else {
          // Do nothing
        }
      }

    } else {
      if (Q.top().cost == D_unused[Q.top().to]) {
        min_index = Q.top().to;
        Q.pop();
      } else {
        Q.pop();
        continue;
      }

      for (int k = 0; k < V[min_index].size(); k++) {
        if (V[min_index][k].used == false) {
          if (D_unused[V[min_index][k].to] >
              D_unused[min_index] + V[min_index][k].cost) {
            D_unused[V[min_index][k].to] =
                D_unused[min_index] + V[min_index][k].cost;
            Q.push(
                Node(V[min_index][k].to, D_unused[V[min_index][k].to], false));
          }
        } else {
          if (D_used[V[min_index][k].to] >
              D_unused[min_index] + V[min_index][k].cost) {
            D_used[V[min_index][k].to] =
                D_unused[min_index] + V[min_index][k].cost;
            Q.push(Node(V[min_index][k].to, D_used[V[min_index][k].to], true));
          }
        }
      }
    }
  }

  printf("%d\\n", min(D_used[N], D_unused[N]));
}

int main() {

  int N, M;

  while (true) {
    scanf("%d %d", &N, &M);
    if (N == 0 && M == 0)
      break;

    func(N, M);
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <stdio.h>
#include <vector>
typedef long long int ll;

#define NUM 2000000000

using namespace std;

int minimum, min_past_num, num_town, m, start, goal;

struct Info {
  Info() {
    current_town = 0;
    index = 0;
    pre_town = 0;
    // go_and_return = false;
  }
  int visited[102];
  int current_town, index, costs[102], pre_town;
  // bool go_and_return;
};

struct Data {
  Data(int arg_to, int arg_cost) {
    to = arg_to;
    cost = arg_cost;
  }
  int to, cost;
};

vector<Data> V[101];

void func(Info info) {

  int sum = 0, maximum = 0;

  if (info.index == 1) {
    sum = info.costs[0];
  } else if (info.index == 2) {
    sum = 0;
  } else {
    sum = info.costs[0] + info.costs[1];
    maximum = sum;

    for (int i = 2; i < info.index; i++) {
      sum += info.costs[i];
      maximum = max(maximum, info.costs[i] + info.costs[i - 1]);
    }
    // rest = sum - info.costs[info.index-1];
    sum = sum - maximum;
  }

  if (info.current_town == goal) {
    minimum = min(minimum, sum);
    return;
  } else {
    if (info.index > 2 && sum >= minimum) {
      return;
    }
  }

  for (int i = 0; i < V[info.current_town].size(); i++) {
    if (info.visited[V[info.current_town][i].to] == 0) {
      Info new_info;
      for (int k = 1; k <= num_town; k++)
        new_info.visited[k] = info.visited[k];
      new_info.visited[V[info.current_town][i].to]++;
      new_info.current_town = V[info.current_town][i].to;
      for (int k = 0; k < info.index; k++)
        new_info.costs[k] = info.costs[k];
      new_info.costs[info.index] = V[info.current_town][i].cost;
      new_info.pre_town = info.current_town;
      new_info.index = info.index + 1;
      // new_info.go_and_return = info.go_and_return;
      func(new_info);
    } else if (info.visited[V[info.current_town][i].to] == 1 &&
               info.pre_town == V[info.current_town][i].to) {
      Info new_info;
      for (int k = 1; k <= num_town; k++)
        new_info.visited[k] = info.visited[k];
      new_info.visited[V[info.current_town][i].to]++;
      new_info.current_town = V[info.current_town][i].to;
      for (int k = 0; k < info.index; k++)
        new_info.costs[k] = info.costs[k];
      new_info.costs[info.index] = V[info.current_town][i].cost;
      new_info.pre_town = info.current_town;
      new_info.index = info.index + 1;
      // new_info.go_and_return = true;
      func(new_info);
    }
  }
}

int main() {

  int from, to, fee;

  start = 1;

  while (true) {
    scanf("%d %d", &num_town, &m);
    if (num_town == 0 && m == 0)
      break;

    goal = num_town;
    minimum = 2000000000;

    for (int i = 1; i <= num_town; i++)
      V[i].clear();

    int costTable[num_town + 1][num_town + 1];

    for (int i = 1; i <= num_town; i++) {
      for (int k = 1; k <= num_town; k++) {
        costTable[i][k] = NUM;
      }
    }

    for (int i = 0; i < m; i++) {
      scanf("%d %d %d", &from, &to, &fee);

      V[from].push_back(Data(to, fee));
      V[to].push_back(Data(from, fee));
      costTable[from][to] = fee;
      costTable[to][from] = fee;
    }

    int past[num_town + 1]; //???????????±????¨??????????????????????
    for (int i = 1; i <= num_town; i++)
      past[i] = 1;

    //????????????????????§??????????????????????????????????????????<??????????????????>
    int D[num_town + 1];
    bool visited[num_town + 1];
    for (int i = 1; i <= num_town; i++) {
      D[i] = NUM;
      visited[i] = false;
    }

    visited[1] = true;

    int count = 1, current_min, current_min_index;

    while (count < num_town) {
      current_min = NUM;
      for (int i = 1; i <= num_town; i++) {
        if (D[i] < current_min &&
            visited[i] ==
                false) { //????????????????????????visited???true????????£???????????????<TE??????PQ?????????>
          current_min = D[i];
          current_min_index = i;
        }
      }

      if (current_min == NUM)
        break;

      visited[current_min_index] = true;
      count++;

      for (int i = 1; i <= num_town; i++) {
        if (costTable[current_min_index][i] != NUM &&
            D[i] > D[current_min_index] + costTable[current_min_index][i]) {
          D[i] = D[current_min_index] + costTable[current_min_index][i];
          past[i] = current_min_index;
        }
      }
    }

    int base_costs[num_town + 1], base_index = 0, t;

    t = goal;
    while (true) {
      base_costs[base_index++] = costTable[t][past[t]];
      t = past[t];
      if (t == 1)
        break;
    }

    int meyasu = 0, meyasu_max = 0;

    if (base_index == 1) {
      minimum = base_costs[0];
    } else if (base_index == 2) {
      minimum = 0;
    } else {
      meyasu = base_costs[0] + base_costs[1];
      meyasu_max = meyasu;

      for (int i = 2; i < base_index; i++) {
        meyasu += base_costs[i];
        meyasu_max = max(meyasu_max, base_costs[i] + base_costs[i - 1]);
      }

      meyasu -= meyasu_max;
      minimum = meyasu;
    }

    Info info;
    for (int i = 1; i <= num_town; i++)
      info.visited[i] = 0;

    info.current_town = start;
    info.visited[start]++;

    func(info);

    printf("%d\\n", minimum);
  }

  return 0;
}