📅  最后修改于: 2023-12-03 15:12:35.205000             🧑  作者: Mango
该问题为 GATE 2017 MOCK II 中的编程问题,出题者希望候选人们通过这道题目来检验其对于树的理解及应用。该问题的难度属于中等偏上。
给定一棵无向树,其中每个非叶节点的权重均为其所有子节点的权重之和,而每个叶节点的权重均为该叶节点所在的路径上所有非叶节点的权重之和。现在,请你编写一个程序,该程序能够接收树的结构和每个节点的权重,并且能够输出所有叶节点的权重之和。
首先,我们需要定义树的节点结构体,包含节点权重以及该节点的子节点(当然,叶子节点的子节点为空):
struct TreeNode {
int weight;
vector<TreeNode *> children;
};
接下来,我们需要编写一个递归函数来遍历整棵树,同时统计每个叶子节点的权重:
int sumLeafNodeWeights(TreeNode *node) {
// 如果当前节点为叶子节点,那么直接返回该节点的权重。
if (node->children.size() == 0) {
return node->weight;
}
// 否则,遍历当前节点的所有子节点
int sum = 0;
for (auto child : node->children) {
// 将当前节点的权重累加所有子节点的权重之和
sum += sumLeafNodeWeights(child);
}
// 如果当前节点不为根节点,那么还需要将该节点的权重累加到其父节点的权重中
if (node->children.size() > 0) {
node->children[0]->weight += node->weight;
}
return sum;
}
最后,在主函数中,我们可以通过依次读入每个节点的权重及其子节点的编号,构建整棵树,并调用 sumLeafNodeWeights()
函数,输出所有叶子节点的权重之和:
int main() {
// 读入节点总数以及树的根节点编号
int n, rootIndex;
cin >> n >> rootIndex;
// 构建每个节点
vector<TreeNode *> nodes(n);
for (int i = 0; i < n; i++) {
int weight, numChildren;
cin >> weight >> numChildren;
nodes[i] = new TreeNode{weight, vector<TreeNode *>()};
// 构建当前节点的所有子节点
for (int j = 0; j < numChildren; j++) {
int childIndex;
cin >> childIndex;
nodes[i]->children.push_back(nodes[childIndex]);
}
}
// 调用sumLeafNodeWeights()函数得到所有叶子节点的权重之和
int sum = sumLeafNodeWeights(nodes[rootIndex]);
// 输出结果
cout << sum << endl;
return 0;
}
该题目需要候选人们深入理解树的概念,同时也考察了他们的递归思维、指针操作等方面的能力。对于没有接触过树的同学,可能需要额外的学习和练习才能够解决这道问题。