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

#include <algorithm>
#include <stdio.h>
#include <vector>

using namespace std;

short heap_index[10000];

struct Info {
  Info() {
    to = 0;
    weight = 0;
  }
  Info(short arg_to, int arg_weight) {
    to = arg_to;
    weight = arg_weight;
  }
  short to;
  int weight;
};

class InfoPQ {
public:
  InfoPQ() {
    array = new Info[10000];
    n = 0;
  }
  void push(Info arg_info) {
    array[n] = arg_info;
    int tmp = n;
    while (tmp != 0 && array[tmp].weight < array[(tmp - 1) / 2].weight) {
      std::swap(array[tmp], array[(tmp - 1) / 2]);
      tmp = (tmp - 1) / 2;
    }
    n++;
  }

  bool isEmpty() { return n == 0; }

  void writeHeapIndex() {
    for (int i = 0; i < n; i++) {
      heap_index[array[i].to] = i;
    }
  }

  void update(short update_index, int new_weight) {
    array[heap_index[update_index]].weight = new_weight;
    int tmp = heap_index[update_index];
    while (tmp != 0 && array[tmp].weight < array[(tmp - 1) / 2].weight) {
      std::swap(heap_index[array[tmp].to], heap_index[array[(tmp - 1) / 2].to]);
      std::swap(array[tmp], array[(tmp - 1) / 2]);
      tmp = (tmp - 1) / 2;
    }
  }

  Info pop() {
    Info ret = array[0];
    n--;
    heap_index[array[n].to] = 0;
    std::swap(array[0], array[n]);
    int tmp = 0;
    while (2 * tmp + 1 <= n - 1) {
      if (2 * tmp + 2 <= n - 1) {
        if (array[2 * tmp + 2].weight < array[tmp].weight &&
            array[2 * tmp + 2].weight <= array[2 * tmp + 1].weight) {
          std::swap(heap_index[array[tmp].to],
                    heap_index[array[2 * tmp + 2].to]);
          std::swap(array[2 * tmp + 2], array[tmp]);
          tmp = 2 * tmp + 2;
        } else if (array[2 * tmp + 1].weight < array[tmp].weight &&
                   array[2 * tmp + 1].weight <= array[2 * tmp + 2].weight) {
          std::swap(heap_index[array[tmp].to],
                    heap_index[array[2 * tmp + 1].to]);
          std::swap(array[2 * tmp + 1], array[tmp]);
          tmp = 2 * tmp + 1;
        } else {
          break;
        }
      } else {
        if (array[tmp].weight > array[2 * tmp + 1].weight) {
          std::swap(heap_index[array[tmp].to],
                    heap_index[array[2 * tmp + 1].to]);
          std::swap(array[tmp], array[2 * tmp + 1]);
          tmp = 2 * tmp + 1;
        } else {
          break;
        }
      }
    }
    return ret;
  }

private:
  Info *array;
  int n;
};

int main() {
  int n, count = 0, tmp, left_node, right_node, dist;
  scanf("%d", &n);
  vector<Info> V[n];
  Info catcher;
  InfoPQ A;

  int P[n], zero_dist[n];

  for (int i = 0; i < n; i++) {
    P[i] = 0;
    zero_dist[i] = 10000001;
  }
  zero_dist[0] = 0;
  P[0] = 1;

  for (int i = 0; i < n; i++) {
    scanf("%d %d", &left_node, &tmp);
    if (left_node == 0) {
      for (int k = 0; k < tmp; k++) {
        scanf("%d %d", &right_node, &dist);
        zero_dist[right_node] = dist;
      }
    } else {
      for (int k = 0; k < tmp; k++) {
        scanf("%d %d", &right_node, &dist);
        V[left_node].push_back(Info(right_node, dist));
      }
    }
  }

  for (short k = 1; k < n; k++) {
    A.push(Info(k, zero_dist[k]));
  }

  A.writeHeapIndex();

  while (count < n - 1) {

    catcher = A.pop();
    P[catcher.to] = 1;
    count++;

    for (int k = 0; k < V[catcher.to].size(); k++) {
      if (zero_dist[V[catcher.to][k].to] >
          catcher.weight + V[catcher.to][k].weight) {
        zero_dist[V[catcher.to][k].to] =
            catcher.weight + V[catcher.to][k].weight;
        A.update(V[catcher.to][k].to, catcher.weight + V[catcher.to][k].weight);
      }
    }
  }

  for (int i = 0; i < n; i++) {
    printf("%d %d\\n", i, zero_dist[i]);
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <stdio.h>
#include <vector>

using namespace std;

struct Info {
  Info() {
    to = 0;
    weight = 0;
  }
  Info(short arg_to, int arg_weight) {
    to = arg_to;
    weight = arg_weight;
  }
  short to;
  int weight;
};

class InfoPQ {
public:
  InfoPQ() {
    array = new Info[10000];
    n = 0;
  }
  void push(Info arg_info) {
    array[n] = arg_info;
    int tmp = n;
    while (tmp != 0 && array[tmp].weight < array[(tmp - 1) / 2].weight) {
      std::swap(array[tmp], array[(tmp - 1) / 2]);
      tmp = (tmp - 1) / 2;
    }
    n++;
  }

  bool isEmpty() { return n == 0; }

  Info pop() {
    Info ret = array[0];
    n--;
    std::swap(array[0], array[n]);
    int tmp = 0;
    while (2 * tmp + 1 <= n - 1) {
      if (2 * tmp + 2 <= n - 1) {
        if (array[2 * tmp + 2].weight < array[tmp].weight &&
            array[2 * tmp + 2].weight <= array[2 * tmp + 1].weight) {
          std::swap(array[2 * tmp + 2], array[tmp]);
          tmp = 2 * tmp + 2;
        } else if (array[2 * tmp + 1].weight < array[tmp].weight &&
                   array[2 * tmp + 1].weight <= array[2 * tmp + 2].weight) {
          std::swap(array[2 * tmp + 1], array[tmp]);
          tmp = 2 * tmp + 1;
        } else {
          break;
        }
      } else {
        if (array[tmp].weight > array[2 * tmp + 1].weight) {
          std::swap(array[tmp], array[2 * tmp + 1]);
          tmp = 2 * tmp + 1;
        } else {
          break;
        }
      }
    }
    return ret;
  }

private:
  Info *array;
  int n;
};

int main() {
  int n, count = 0, tmp, left_node, right_node, dist, t_to_i;
  scanf("%d", &n);
  vector<Info> V[n];
  InfoPQ A, B;

  Info catcher, tmp_catcher;

  int P[n], zero_dist[n];

  for (int i = 0; i < n; i++) {
    P[i] = 0;
    zero_dist[i] = 10000001;
  }
  zero_dist[0] = 0;
  P[0] = 1;

  for (int i = 0; i < n; i++) {
    scanf("%d %d", &left_node, &tmp);
    if (left_node == 0) {
      for (int k = 0; k < tmp; k++) {
        scanf("%d %d", &right_node, &dist);
        zero_dist[right_node] = dist;
      }
    } else {
      for (int k = 0; k < tmp; k++) {
        scanf("%d %d", &right_node, &dist);
        V[left_node].push_back(Info(right_node, dist));
      }
    }
  }

  for (short k = 1; k < n; k++) {
    A.push(Info(k, zero_dist[k]));
  }

  while (count < n - 1) {
    if (count % 2 == 0) {
      catcher = A.pop();
      P[catcher.to] = 1;
      count++;

      while (!A.isEmpty()) {
        tmp_catcher = A.pop();
        t_to_i = 10000001;
        for (int k = 0; k < V[catcher.to].size(); k++) {
          if (V[catcher.to][k].to == tmp_catcher.to) {
            t_to_i = V[catcher.to][k].weight;
            break;
          }
        }
        if (tmp_catcher.weight > catcher.weight + t_to_i) {
          tmp_catcher.weight = catcher.weight + t_to_i;
          zero_dist[tmp_catcher.to] = catcher.weight + t_to_i;
        }
        B.push(tmp_catcher);
      }
    } else {
      catcher = B.pop();
      P[catcher.to] = 1;
      count++;

      while (!B.isEmpty()) {
        tmp_catcher = B.pop();
        t_to_i = 10000001;
        for (int k = 0; k < V[catcher.to].size(); k++) {
          if (V[catcher.to][k].to == tmp_catcher.to) {
            t_to_i = V[catcher.to][k].weight;
            break;
          }
        }
        if (tmp_catcher.weight > catcher.weight + t_to_i) {
          tmp_catcher.weight = catcher.weight + t_to_i;
          zero_dist[tmp_catcher.to] = catcher.weight + t_to_i;
        }
        A.push(tmp_catcher);
      }
    }
  }

  for (int i = 0; i < n; i++) {
    printf("%d %d\\n", i, zero_dist[i]);
  }

  return 0;
}