员工的信息定义如下:
class TreeNode{ public: int happy; //这名员工可以带来的快乐值 vector<TreeNode*> next; //这名员工有哪些直接下级 TreeNode(int h):happy(h){} //初始化 };
1、递归套路思路
对于任意一个以X为头,含有a、b、c三个子节点的多叉树,最大快乐值分为两种:
(1)X来参加派对
最大快乐值 = X.happy
+ a不来的max(happy)
+ b不来的max(happy)
+ c不来的max(happy)
(2)X不来参加派对
最大快乐值 = max( a来的max(happy), a不来的max(happy) )
+ max( b来的max(happy), b不来的max(happy) )
+ max( c来的max(happy), c不来的max(happy) )
最后,最大的快乐值为以上两种情况的最大值。
可定义如下:class Max{ public: int no; //不来的最大收益 int yes; //来的最大收益 Max(int n,int y):no(n),yes(y){} //初始化 };
2、递归套路代码
Max getMax(TreeNode* root){
if(root->next.empty()) return Max(0,root->happy); //判断到根节点返回(不来,来)两种情况
int n=0; //root不来的最大快乐值
int y=root->happy; //root来的最大快乐值
for(auto r:root->next){ //遍历每一个直接孩子
auto k=getMax(r); //获取以子孩子位根的子树的快乐情况
y+=k.no; //root来,那么所有孩子都不能来
n+=max(k.yes,k.no); //root不来,所有孩子 来与不来 两种情况选择最大值
}
return Max(n,y);
}
3、完整代码
#include<bits/stdc++.h> using namespace std; class TreeNode{ public: int happy; vector<TreeNode*> next; TreeNode(int h):happy(h){} }; class Max{ public: int no; int yes; Max(int n,int y):no(n),yes(y){} }; Max getMax(TreeNode* root){ if(root->next.empty()) return Max(0,root->happy); int n=0,y=root->happy; for(auto r:root->next){ auto k=getMax(r); y+=k.no; n+=max(k.yes,k.no); } return Max(n,y); } int main(){ int n,root; cin>>n>>root; vector<TreeNode*> happy(n); int t,u,v; for(int i=0;i<n;++i){ cin>>t; happy[i]=new TreeNode(t); } for(int i=1;i<n;++i){ cin>>u>>v; happy[u-1]->next.push_back(happy[v-1]); } auto x=getMax(happy[root-1]); cout<< max(x.no,x.yes) <<endl; return 0; }