题目大意
给出一棵家谱树,树中的节点都有一个名字,保证每个名字都是唯一的,然后进行若干次查询,找出两个名字的最近公共祖先。
分析
数据量较小,对于每次查询都进行如下操作:
先找出person1到达根节点的路径path,然后再从person2开始向上,每经过一个节点都查询一下该节点是否在path中出现,如果出现,则为该节点。
实现
#include<iostream> #include<string.h> #include<stdio.h> #include<unordered_map> #include<unordered_set> #include<string> #include<stack> using namespace std; unordered_set<string> path; //存储从一个节点到根节点的路径 unordered_map<string, string> pre; //存储图的结构,通过 <key, value> key为子节点,value为 父节点 int main(){ int n, m; string father, son, person1, person2; cin >> n; for (int i = 0; i < n; i++){ cin >> father >> son; pre[son] = father; } cin >> m; for (int i = 0; i < m; i++){ cin >> person1 >> person2; path.clear(); //存储从person1 到根节点的路径 while (pre.find(person1) != pre.end()){ path.insert(person1); person1 = pre[person1]; } path.insert(person1); //进行查找 bool find = false; while (pre.find(person2) != pre.end()){ person2 = pre[person2]; if (path.find(person2) != path.end()){ find = true; cout << person2 << endl; break; } } //person2此时为根节点,需要注意(不要忘记查找)! if (!find &&path.find(person2) != path.end()){ cout << person2 << endl; } if (!find) cout << -1 << endl; } return 0; }