题目描述
计算一棵二叉树的带权路径总和,即求赫夫曼树的带权路径和。已知一棵二叉树的叶子权值,该二叉树的带权案路径和APL等于叶子权值乘于根节点到叶子的分支数,然后求总和。如下图中,叶子都用大写字母表示,权值对应为:A-7,B-6,C-2,D-3
树的带权路径和 = 71 + 62 + 23 + 33 = 34
本题二叉树的创建参考前面的方法
输入
第一行输入一个整数t,表示有t个二叉树第二行输入一棵二叉树的先序遍历结果,空树用字符‘0’表示,注意输入全是英文字母和0,其中大写字母表示叶子
第三行先输入n表示有n个叶子,接着输入n个数据表示n个叶子的权值,权值的顺序和前面输入的大写字母顺序对应
以此类推输入下一棵二叉树
输出
输出每一棵二叉树的带权路径和
样例输入
2
xA00tB00zC00D00
4 7 6 2 3
ab0C00D00
2 10 20
样例输出
34
40
本题使用了《广度优先搜索方法》,而不是递归,解题思路是判断每一层的结点是否为叶子结点,如果为叶子结点,根据层数相乘加到总和sum,最后返回sum
#include<iostream>
#include<queue>
using namespace std;
class Node {
public:
char data;
int quan;
Node *lchild, *rchild;
Node(char _data) {
data = _data;
lchild = NULL;
rchild = NULL;
quan = 0;
}
Node(){
lchild = NULL;
rchild = NULL;
quan = 0;
}
~Node() {
if (lchild != NULL) {
delete lchild;
}
if (rchild != NULL) {
delete rchild;
}
}
};
class BinaryTree {
public:
Node *root;
BinaryTree() {
root = NULL;
}
~BinaryTree() {
delete root;
}
};
void build(Node *&tree){
char c;
cin>>c;
if(c == '0'){
tree = NULL;
}
if(c != '0'){
tree = new Node(c);
build(tree->lchild);
build(tree->rchild);
}
}
void input(Node *&node){
if(!node) return;
if(node->lchild == NULL && node->rchild == NULL){
cin>>node->quan;
return ;
}
input(node->lchild);
input(node->rchild);
}
int sum_road(Node *node){
queue<Node *> que;
que.push(node);
int floor = -1,sum = 0;
while(!que.empty()){
floor++;
int size = que.size();
while(size--){
Node* temp = que.front();
que.pop();
if(!temp){
continue;
}
if(temp->lchild == NULL && temp->rchild ==NULL){
sum += temp->quan*floor;
}
que.push(temp->lchild);
que.push(temp->rchild);
}
}
return sum;
}
int main() {
int t;
cin>>t;
while(t--) {
BinaryTree binarytree;
build(binarytree.root);
char c;
cin>>c;
input(binarytree.root);
cout<<sum_road(binarytree.root)<<endl;
}
return 0;
}