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

#include <cassert>
#include <climits>
#include <fstream>
#include <iostream>
#include <stdint.h>
#include <stdio.h>
#include <vector>
using namespace std;

#define DEBUG (0)

#if DEBUG
#define DPRINTF(...)                                                           \\
  do {                                                                         \\
    printf("D(L%d) %s: ", __LINE__, __func__);                                 \\
    printf(__VA_ARGS__);                                                       \\
  } while (false)
#else
#define DPRINTF(...)
#endif // DEBUG

struct Node {
  Node() : id_(-1), depth_(-1), parentId_(-1) {}
#if 0
    parent_(nullptr) { }
#endif

  int id_;
#if 0
  Node*         parent_;
#endif
  int parentId_;
  int depth_;
  vector<Node *> leafs_; // TODO: check if memory allocated contiguously?
  /*
    uint8_t   depth;
  */
};

#if 0
Node* getRoot(const Node* node)
{
  assert(node != nullptr);

  if (node->parent_ == nullptr)
    return node;
  else
    return getRoot(node->parent_);
}
#endif
Node *getRoot(Node *node, uint32_t numOfNodes) {
  for (uint32_t i = 0; i < numOfNodes; i++) {
    if (node[i].parentId_ == -1)
      return &node[i];
  }

  assert(false);
  return nullptr;
}

#if 0
bool traverse(const Node* node, int id, int depth)
{
  //DPRINTF("node %p  id %d  depth %d\\n", node, id, depth);

  if (node == nullptr)
    return false;

  if (id == node->id_)
  {
    int parentId = -1;
    if (node->parent_ != nullptr)
      parentId = node->parent_->id_;

    string type;
    if (depth == 0)
      type = "root";
    else if (node->leafs_.size() == 0)
      type = "leaf";
    else
      type = "internal node";

    printf("node %d: ", id);
    printf("parent = %d, ", parentId);
    printf("depth = %d, ", depth);
    printf("%s, ", type.c_str());
    printf("[");
    for (uint32_t i = 0; i < node->leafs_.size(); i++) {
      if (i == 0) printf("%d",   node->leafs_[i]->id_);
      else        printf(", %d", node->leafs_[i]->id_);
    }
    printf("]");

    cout << endl;

    return true;
  }

  for (uint32_t i = 0; i < node->leafs_.size(); i++)
  {
    if (traverse(node->leafs_[i], id, depth + 1))
      return true;
  }

  return false;
}
#endif

void setDepth(Node *node, int depth) {
  if (node == nullptr)
    return;

  node->depth_ = depth;

  for (uint32_t i = 0; i < node->leafs_.size(); i++) {
    setDepth(node->leafs_[i], depth + 1);
  }
}

int main() {
  uint32_t numOfNodes;
  cin >> numOfNodes;
  cin.ignore();

  Node *nodes = new Node[numOfNodes];

  for (uint32_t i = 0; i < numOfNodes; i++) {
    int id;
    uint32_t degree;
    cin >> id;
    cin >> degree;

    nodes[id].id_ = id;

    for (uint32_t j = 0; j < degree; j++) {
      uint32_t cid; // the ids will be always sorted in ascending order?
      cin >> cid;
      nodes[id].leafs_.push_back(&nodes[cid]);
#if 0
      nodes[cid].parent_ = &nodes[id];
#endif
      nodes[cid].parentId_ = id;
    }

    cin.ignore();
  }

#if DEBUG
  for (uint32_t i = 0; i < numOfNodes; i++) {
    DPRINTF("%d %lu", nodes[i].id_, nodes[i].leafs_.size());
    for (uint32_t j = 0; j < nodes[i].leafs_.size(); j++) {
      printf(" %d", nodes[i].leafs_[j]->id_);
    }
    printf("\\n");
  }
#endif

#if 0
  Node* root = getRoot(&nodes[0]); // Assume that tree has the only one root
#endif
  Node *root =
      getRoot(nodes, numOfNodes); // Assume that tree has the only one root

  setDepth(root, 0);

  for (uint32_t i = 0; i < numOfNodes; i++) {
    // traverse(root, i, 0);

    Node *node = &nodes[i];

    string type;
    if (node->depth_ == 0)
      type = "root";
    else if (node->leafs_.size() == 0)
      type = "leaf";
    else
      type = "internal node";

    printf("node %d: ", i);
    printf("parent = %d, ", node->parentId_);
    printf("depth = %d, ", node->depth_);
    printf("%s, ", type.c_str());
    printf("[");
    for (uint32_t i = 0; i < node->leafs_.size(); i++) {
      if (i == 0)
        printf("%d", node->leafs_[i]->id_);
      else
        printf(", %d", node->leafs_[i]->id_);
    }
    printf("]");

    cout << endl;
  }

  delete[] nodes;

  return 0;
}


Error: TLE

Fixed submission:

#include <cassert>
#include <climits>
#include <fstream>
#include <iostream>
#include <stdint.h>
#include <stdio.h>
#include <vector>
using namespace std;

#define DEBUG (0)

#if DEBUG
#define DPRINTF(...)                                                           \\
  do {                                                                         \\
    printf("D(L%d) %s: ", __LINE__, __func__);                                 \\
    printf(__VA_ARGS__);                                                       \\
  } while (false)
#else
#define DPRINTF(...)
#endif // DEBUG

struct Node {
  Node() : id_(-1), parent_(nullptr) {}
  int id_;
  Node *parent_;
  vector<Node *> leafs_; // TODO: check if memory allocated contiguously?
  /*
    uint8_t   depth;
  */
};

Node *getRoot(Node *node) {
  assert(node != nullptr);

  if (node->parent_ == nullptr)
    return node;
  else
    return getRoot(node->parent_);
}

bool traverse(const Node *node, int id, int depth) {
  // DPRINTF("node %p  id %d  depth %d\\n", node, id, depth);

  if (node == nullptr)
    return false;

  if (id == node->id_) {
    int parentId = -1;
    if (node->parent_ != nullptr)
      parentId = node->parent_->id_;

    string type;
    if (depth == 0)
      type = "root";
    else if (node->leafs_.size() == 0)
      type = "leaf";
    else
      type = "internal node";

    printf("node %d: ", id);
    printf("parent = %d, ", parentId);
    printf("depth = %d, ", depth);
    printf("%s, ", type.c_str());
    printf("[");
    for (uint32_t i = 0; i < node->leafs_.size(); i++) {
      if (i == 0)
        printf("%d", node->leafs_[i]->id_);
      else
        printf(", %d", node->leafs_[i]->id_);
    }
    printf("]");

    cout << endl;

    return true;
  }

  for (uint32_t i = 0; i < node->leafs_.size(); i++) {
    if (traverse(node->leafs_[i], id, depth + 1))
      return true;
  }

  return false;
}

int main() {
  uint32_t numOfNodes;
  cin >> numOfNodes;
  cin.ignore();

  Node *nodes = new Node[numOfNodes];

  for (uint32_t i = 0; i < numOfNodes; i++) {
    int pid;
    uint32_t degree;
    cin >> pid;
    cin >> degree;

    nodes[pid].id_ = pid;

    for (uint32_t j = 0; j < degree; j++) {
      uint32_t cid; // the ids will be always sorted in ascending order?
      cin >> cid;
      nodes[pid].leafs_.push_back(&nodes[cid]);
      nodes[cid].parent_ = &nodes[pid];
    }

    cin.ignore();
  }

#if DEBUG
  for (uint32_t i = 0; i < numOfNodes; i++) {
    DPRINTF("%d %lu", nodes[i].id_, nodes[i].leafs_.size());
    for (uint32_t j = 0; j < nodes[i].leafs_.size(); j++) {
      printf(" %d", nodes[i].leafs_[j]->id_);
    }
    printf("\\n");
  }
#endif

  Node *root = getRoot(&nodes[0]); // Assume that tree has the only one root

  for (uint32_t i = 0; i < numOfNodes; i++) {
    traverse(root, i, 0);
  }

  delete[] nodes;

  return 0;
}