17-好子树
问题描述:

输入输出示例:

思想:采用递归的思想,从根节点出发,递归遍历子节点,然后用两个变量记录当前子树下的最大值和最下值。特别注意以引用的形式记录最大值和最小值,这样能保证把子树的值都传递上来。
代码实现:
#include <iostream>
#include <vector>
using namespace std;
vector<int> res;
int getresult(int index,vector<vector<int>>&edges,vector<int>&nums,int& maxnum,int& minnum){
int ma = nums[index];
int mi = nums[index];
int n = 0;
for(auto a : edges[index]){
n += getresult(a,edges,nums,ma,mi);
}
// 更新最大值和最小值
maxnum = max(maxnum,ma);
minnum = min(minnum,mi);
// 此时的ma和mi已经被更新了
// 这里的都是ma和mi都是当前子树中的最大值和最子值.
if((ma -mi ) % 2 == 1){
n++;
nums[index] = -1;
}
return n;
}
int main() {
// int a, b;
// while (cin >> a >> b) { // 注意 while 处理多个 case
// cout << a + b << endl;
// }
int n;
cin >> n;
vector<int> nums(n);
for(int i = 0;i < n;i++){
cin >> nums[i];
}
int u,v;
// 记录边节点
vector<vector<int>> edges(n);
while(cin >> u >> v){
edges[u-1].emplace_back(v-1);
}
int maxnum = nums[0];
int minnum = nums[0];
int res = getresult(0, edges, nums, maxnum, minnum);
cout << res << endl;
for(int i = 0;i<n;i++){
if(nums[i] == -1){
cout << i+ 1 << " ";
}
}
return 0;
}
// 64 位输出请用 printf("%lld")

浙公网安备 33010602011771号