问题思路:
- 在不断输入的过程中,可以通过层深和一个二维的vector数组来建立一棵树。
- 即每输入一个节点,应当作为该节点上一层的最后一个节点的子孩子。
- 用一个哈希value来指定节点的id,通过一个last记录每个节点id(此时作为last的下标)的父节点是谁。
- 事实上,这种溯源的思路在之前的这道题中也有体现,只不过那里是图,这里是树。【PAT甲级】1175 Professional Ability Test(30分)[dijkstra(优先队列),拓扑排序]
代码实现:
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
using namespace std;
int n;
vector<string> last(1005);
unordered_map<string, int> value;
void buildTree() {
vector<vector<string>> Tree(1005, vector<string>()); // 每一个节点作为每一层深的最后一个节点的子孩子
int cnt = 0;
cin >> n;
cin.ignore(); // Clear the newline character from the input buffer
for (int i = 0; i < n; i++) {
string line;
getline(cin, line);
int depth = line.find_first_not_of(' '); // 层深
string id = line.substr(depth, 4); // 节点字符串
value[id] = cnt;
Tree[depth].push_back(id);
if (depth > 0) {
last[cnt] = Tree[depth - 1].back(); // 每个节点记录上一层的父节点是谁
}
cnt += 1;
}
return ;
}
vector<string> findPath(const string& target) {
vector<string> path;
if (value.find(target) == value.end()) return path;
string now = target;
while (now != "0000") {
path.push_back(now);
now = last[value[now]];
}
path.push_back("0000");
return path;
}
int main() {
buildTree();
int k;
cin >> k;
for (int i = 0; i < k; i++) {
string query;
cin >> query;
vector<string> path = findPath(query);
if (!path.empty()) {
for (int i = path.size() - 1; i >= 0; i--) {
cout << path[i];
i && printf("->");
}
printf("\n");
} else {
cout << "Error: " << query << " is not found." << endl;
}
}
return 0;
}