Problem p00797 (C++) — buggy submission, verdict: Runtime Error

#include <cassert>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct node {
  string name;
  vector<node *> childlen;

  node(string name) : name(name) {}
};

void add_child(node *p, string new_name, const vector<string> &path,
               int depth) {
  if (depth == (int)path.size()) {
    p->childlen.push_back(new node(new_name));
    return;
  }
  for (int i = 0; i < (int)p->childlen.size(); ++i) {
    if (path[depth] == p->childlen[i]->name) {
      add_child(p->childlen[i], new_name, path, depth + 1);
    }
  }
  return;
}

void print(node *p) {
  cout << p->name << endl;
  cout << "Childlen :" << endl;
  for (int i = 0; i < (int)p->childlen.size(); ++i) {
    cout << p->childlen[i]->name << endl;
  }
  cout << "-----" << endl << endl;
  for (int i = 0; i < (int)p->childlen.size(); ++i) {
    print(p->childlen[i]);
  }
}

bool isChild;
bool isDescendant;
bool isSibling;
void judge(node *p, const string &a, const string &b, const string &rel,
           bool Xfnd) {
  if (p->name == b) {
    if (Xfnd) {
      isDescendant = true;
    }
    return;
  }

  for (int i = 0; i < (int)p->childlen.size(); ++i) {
    for (int j = i + 1; j < (int)p->childlen.size(); ++j) {
      if ((p->childlen[i]->name == a && p->childlen[j]->name == b) ||
          (p->childlen[i]->name == b && p->childlen[j]->name == a)) {
        isSibling = true;
      }
    }
  }

  for (int i = 0; i < (int)p->childlen.size(); ++i) {
    if (rel == "child") {
      if (p->name == a && p->childlen[i]->name == b && rel == "child") {
        isChild = true;
        return;
      }
    }
    judge(p->childlen[i], a, b, rel, p->name == a | Xfnd);
  }
  return;
}

int main() {
  while (true) {
    int n, m;
    string dam;
    cin >> n >> m;
    if (n == 0 && m == 0)
      break;

    getline(cin, dam);
    node *root = new node("___ROOT");

    int spaces = -1;
    vector<string> path;
    for (int i = 0; i < n; ++i) {
      string s;
      getline(cin, s);

      int csp = 0;
      for (int j = 0; j < (int)s.length(); ++j) {
        if (s[j] == ' ')
          ++csp;
        else
          break;
      }
      s = s.substr(csp);

      if (csp < spaces) {
        path.pop_back();
        for (int j = 0; j < spaces - csp; ++j) {
          path.pop_back();
        }
        add_child(root, s, path, 0);
        path.push_back(s);

      } else if (csp == spaces) {
        path.pop_back();
        add_child(root, s, path, 0);
        path.push_back(s);

      } else if (csp == spaces + 1) {
        add_child(root, s, path, 0);
        path.push_back(s);
      }

      spaces = csp;
    }
    // print(root);

    for (int i = 0; i < m; ++i) {
      string X, Y, rel;
      bool res = false;
      cin >> X >> dam >> dam >> rel >> dam >> Y;
      Y = Y.substr(0, Y.length() - 1);
      if (rel == "parent") {
        rel = "child";
        swap(X, Y);
      }
      if (rel == "ancestor") {
        rel = "descendant";
        swap(X, Y);
      }

      isDescendant = false;
      isChild = false;
      isSibling = false;

      judge(root, Y, X, rel, false);

      if (rel == "child") {
        res = isChild;
      } else if (rel == "descendant") {
        res = isDescendant;
      } else if (rel == "sibling") {
        res = isSibling;
      }

      if (res) {
        cout << "True" << endl;
      } else {
        cout << "False" << endl;
      }
    }
    cout << endl;
  }

  return 0;
}

Error: WA

Fixed submission:

#include <cassert>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct node {
  string name;
  vector<node *> childlen;

  node(string name) : name(name) {}
};

void add_child(node *p, string new_name, const vector<string> &path,
               int depth) {
  if (depth == (int)path.size()) {
    p->childlen.push_back(new node(new_name));
    return;
  }
  for (int i = 0; i < (int)p->childlen.size(); ++i) {
    if (path[depth] == p->childlen[i]->name) {
      add_child(p->childlen[i], new_name, path, depth + 1);
    }
  }
  return;
}

void print(node *p) {
  cout << "Childlen :" << endl;
  for (int i = 0; i < (int)p->childlen.size(); ++i) {
    cout << p->childlen[i]->name << endl;
  }
  cout << "-----" << endl;
  for (int i = 0; i < (int)p->childlen.size(); ++i) {
    print(p->childlen[i]);
  }
}

bool judge(node *p, const string &a, const string &b, const string &rel,
           bool Xfnd) {
  // cout << a << ' ' << b << ' ' << p->name << endl;
  if (p->name == b) {
    return Xfnd;
  }

  for (int i = 0; i < (int)p->childlen.size(); ++i) {
    for (int j = i + 1; j < (int)p->childlen.size(); ++j) {
      if ((p->childlen[i]->name == a && p->childlen[j]->name == b) ||
          (p->childlen[i]->name == b && p->childlen[j]->name == a)) {
        return true;
      }
    }
  }

  for (int i = 0; i < (int)p->childlen.size(); ++i) {
    if (p->name == a && p->childlen[i]->name == b && rel == "child")
      return true;
    if (judge(p->childlen[i], a, b, rel, p->name == a))
      return true;
  }
  return false;
}

int main() {
  while (true) {
    int n, m;
    string dam;
    cin >> n >> m;
    if (n == 0 && m == 0)
      break;

    getline(cin, dam);
    node *root = new node("_PARENT_");

    int spaces = -1;
    string current_parent = "---";
    vector<string> path;
    for (int i = 0; i < n; ++i) {
      string s;
      getline(cin, s);

      int csp = 0;
      for (int j = 0; j < (int)s.length(); ++j) {
        if (s[j] == ' ')
          ++csp;
        else
          break;
      }
      s = s.substr(csp);

      /*
      cout << current_parent << ' ' << s << ' ' << spaces << ' ' << csp << endl;
      for(int j = 0; j < (int)path.size(); ++j){
        cout << path[j] << endl;
      }
      cout << endl;
      */

      if (csp == spaces - 1) {
        path.pop_back();
        path.pop_back();
        add_child(root, s, path, 0);
        path.push_back(s);

      } else if (csp == spaces) {
        path.pop_back();
        add_child(root, s, path, 0);
        path.push_back(s);

      } else if (csp == spaces + 1) {
        add_child(root, s, path, 0);
        path.push_back(s);

      } else
        assert(false);

      spaces = csp;
    }

    for (int i = 0; i < m; ++i) {
      string X, Y, rel;
      cin >> X >> dam >> dam >> rel >> dam >> Y;
      Y = Y.substr(0, Y.length() - 1);
      if (rel == "parent") {
        rel = "child";
        swap(X, Y);
      }
      if (rel == "ancestor") {
        rel = "descendant";
        swap(X, Y);
      }

      if (judge(root, Y, X, rel, false)) {
        cout << "True" << endl;
      } else {
        cout << "False" << endl;
      }
    }
    cout << endl;
  }

  return 0;
}