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

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <vector>

using namespace std;

int m, n;

struct nodeInfo {
  int depth;
};

map<string, int> id;
vector<int> G[1010];
nodeInfo nif[1010];

int backNode(int cnode, int cnt) {
  for (int i = 0; i < cnt; i++) {
    for (int j = 0; j < G[cnode].size(); j++) {
      // ツ親ツノツーツドツづ個づ卍つ、ツつェツ深ツつウツつェツ静ウツつ「
      if (nif[G[cnode][j]].depth < nif[cnode].depth) {
        cnode = G[cnode][j];
        break;
      }
    }
  }
  return cnode;
}
bool isChild(int n1idx, int n2idx) { return n2idx == backNode(n1idx, 1); }
bool isAncestor(int n1idx, int n2idx) {
  int cnode = n2idx;
  while (1) {
    if (cnode == n1idx)
      return true;
    // ツ親ツづ可つウツつゥツづ個づ堋づゥ
    if (cnode == 0)
      return false;
    else
      cnode = backNode(cnode, 1);
  }
}

int main() {
  while (cin >> n >> m && !(n == 0 && m == 0)) {
    id.clear();
    string str;
    getline(cin, str);
    for (int i = 0; i < 1010; i++)
      G[i].clear();
    int depth = -1;
    int cp = -1;
    for (int i = 0; i < n; i++) {
      getline(cin, str);
      int cnt = 0;
      for (int j = 0;; j++) {
        if (str[j] == ' ')
          continue;
        else {
          str = str.substr(j);
          cnt = j;
          break;
        }
      }
      id[str] = i;
      // cntツづ個青板つセツつッツ親ツづ可姪淞づィツ、ツつサツつアツづ可ノツーツドツづーツ挿ツ禿シツつキツづゥ
      if (cp != -1) {
        if (depth < cnt) {
          G[cp].push_back(i);
          G[i].push_back(cp);
        } else {
          int back = backNode(cp, depth - cnt + 1);
          G[back].push_back(i);
          G[i].push_back(back);
        }
      }
      cp = i;
      depth = cnt;
      nif[i].depth = depth;
    }
    for (int j = 0; j < m; j++) {
      string name1, name2, tmp, order;
      cin >> name1 >> tmp >> tmp >> order >> tmp >> name2;
      name2 = name2.substr(0, name2.size() - 1);
      int n1idx = id[name1];
      int n2idx = id[name2];
      bool match = false;
      if (order == "child")
        match = isChild(n1idx, n2idx);
      else if (order == "ancestor")
        match = isAncestor(n1idx, n2idx);
      else if (order == "sibling") {
        int cnode = backNode(n1idx, 1);
        for (int i = 0; i < G[cnode].size(); i++) {
          int to = G[cnode][i];
          match = (nif[n1idx].depth == nif[to].depth && to == n2idx);
          if (match)
            break;
        }
      } else if (order == "parent")
        match = isChild(n2idx, n1idx);
      else
        match = isAncestor(n2idx, n1idx);
      if (match)
        cout << "True" << endl;
      else
        cout << "False" << endl;
    }
    cout << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <vector>

using namespace std;

int m, n;

struct nodeInfo {
  int depth;
};

map<string, int> id;
vector<int> G[1010];
nodeInfo nif[1010];

int main() {
  bool f = false;
  while (cin >> n >> m && !(n == 0 && m == 0)) {
    if (f)
      cout << endl;
    f = true;
    id.clear();
    string str;
    getline(cin, str);
    for (int i = 0; i < 1010; i++)
      G[i].clear();
    int depth = -1;
    int cp = -1;
    for (int i = 0; i < n; i++) {
      getline(cin, str);
      int cnt = 0;
      for (int j = 0;; j++) {
        if (str[j] == ' ')
          continue;
        else {
          str = str.substr(j);
          cnt = j;
          break;
        }
      }
      id[str] = i;
      // cntツづ個青板つセツつッツ親ツづ可姪淞づィツ、ツつサツつアツづ可ノツーツドツづーツ挿ツ禿シツつキツづゥ
      if (cp == -1)
        cp = i;
      else if (depth < cnt) {
        G[cp].push_back(i);
        G[i].push_back(cp);
        cp = i;
      } else if (depth == cnt) {
        int back = G[cp][0];
        G[back].push_back(i);
        G[i].push_back(back);
        cp = i;
      } else if (depth > cnt) {
        // ツ債キツ閉ェツづ個深ツつウツつセツつッツ親ツづ鳴姪淞づゥ
        for (int j = 0; j <= depth - cnt; j++) {
          int back = G[cp][0];
          cp = back;
        }
        G[cp].push_back(i);
        G[i].push_back(cp);
        cp = i;
      }
      depth = cnt;
      nif[i].depth = depth;
    }
    for (int j = 0; j < m; j++) {
      string name1, name2;
      string tmp;
      string order;
      cin >> name1 >> tmp >> tmp >> order >> tmp >> name2;
      name2 = name2.substr(0, name2.size() - 1);
      int n1idx = id[name1];
      int n2idx = id[name2];
      bool match = false;
      if (order == "child") {
        for (int i = 0; i < G[n2idx].size(); i++) {
          if (nif[G[n2idx][i]].depth > nif[n2idx].depth &&
              G[n2idx][i] == n1idx) {
            match = true;
            break;
          }
        }
      } else if (order == "ancestor") {
        int cnode = n2idx;
        while (1) {
          if (cnode == n1idx) {
            match = true;
            break;
          }
          // ツ親ツづ可つウツつゥツづ個づ堋づゥ
          if (cnode == 0)
            break;
          else {
            for (int i = 0; i < G[cnode].size(); i++) {
              if (nif[G[cnode][i]].depth < nif[depth].depth) {
                cnode = G[cnode][i];
                break;
              }
            }
          }
        }
      } else if (order == "sibling") {
        int cnode = n2idx;
        // ツ暗ェツづつ親ツづ可姪淞づゥ
        for (int i = 0; i < G[cnode].size(); i++) {
          if (nif[G[cnode][i]].depth < nif[depth].depth) {
            cnode = G[cnode][i];
            break;
          }
        }
        for (int i = 0; i < G[cnode].size(); i++) {
          if (G[cnode][i] == n1idx) {
            match = true;
            break;
          }
        }
      } else if (order == "parent") {
        swap(n2idx, n1idx);
        for (int i = 0; i < G[n2idx].size(); i++) {
          if (nif[G[n2idx][i]].depth > nif[n2idx].depth &&
              G[n2idx][i] == n1idx) {
            match = true;
            break;
          }
        }
      } else {
        swap(n2idx, n1idx);
        int cnode = n2idx;
        while (1) {
          if (cnode == n1idx) {
            match = true;
            break;
          }
          // ツ親ツづ可つウツつゥツづ個づ堋づゥ
          if (cnode == 0)
            break;
          else {
            for (int i = 0; i < G[cnode].size(); i++) {
              if (nif[G[cnode][i]].depth < nif[depth].depth) {
                cnode = G[cnode][i];
                break;
              }
            }
          }
        }
      }
      if (match)
        cout << "True" << endl;
      else
        cout << "False" << endl;
    }
  }

  return 0;
}