基本思想:
其实用二叉树更简单一点,但是个人认为题目有可能不太严谨,会出现多棵树情况,用二叉树一样的还是要判断节点是否在一棵树上,没啥必要;
关键点:
无;
#include<iostream> #include<string> #include<vector> #include<algorithm> #include<set> #include<cmath> using namespace std; const int maxn = 26; int father[maxn]; void init() { for (int i = 0; i < maxn; i++) { father[i] = i; } } int findfather(int n) { while (father[n] != n) n = father[n]; return n; } void Union(int a, int b) { father[b] = a; } int find_level(int n) { int cnt = 0; while (father[n] != n) { cnt++; n = father[n]; } return cnt; } bool is_stright(int a, int b) { int t1 = a; int t2 = b; while (t1 != father[t1]) { t1 = father[t1]; if (b == t1) return true; } while (t2 != father[t2]) { t2 = father[t2]; if (a == t2) return true; } return false; } void charge(int a, int b) { int aa = find_level(a); int bb = find_level(b); int cnt = aa - bb; if (cnt > 0) { //爷爷辈; if (cnt == 1) { cout << "parent" << endl; } else { string s = "grandparent"; while (cnt != 2) { cnt--; s = "great-" + s; } cout << s << endl; } } else { cnt = abs(cnt); //孙子辈; if (cnt == 1) { cout << "child" << endl; } else { string s = "grandchild"; while (cnt != 2) { cnt--; s = "great-" + s; } cout << s << endl; } } } int main() { int m, n; string s; while (cin >> n >> m) { init(); for (int i = 0; i < n; i++) { cin >> s; for (int i = 1; i < 3; i++) { if (s[i] != ‘-‘) Union(s[0] - ‘A‘, s[i] - ‘A‘); } } for (int i = 0; i < m; i++) { cin >> s; if (!is_stright(s[0] - ‘A‘, s[1] - ‘A‘)) { cout << ‘-‘ << endl; continue; } charge(s[0] - ‘A‘, s[1] - ‘A‘); } } }
原文:https://www.cnblogs.com/songlinxuan/p/12490198.html