牛客小白月赛29 种树 题解(思维)
题目链接
题目大意
给你一个二叉树,节点要么没有儿子,要么有两个儿子
你每次可以删除两个父亲相同的叶子节点,直到最后剩下一个根节点
显然要删除m=(n-1)/2次
有两种删除方法
第一种:val(x)=max(val(左儿子),val(右儿子) )
第二种:val(x)=min(val(左儿子),val(右儿子) )
最多进行(m+1)/2次第一种操作,要你求根节点的最大值
题目思路
只要根节点的depth[i]<=(m+1)/2,即可以变成根节点的权值
代码
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define fi first
#define se second
#define debug printf(" I am here\n");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=5e5+5,inf=0x3f3f3f3f,mod=2017;
const double eps=1e-10;
int n,dep[maxn],a[maxn];
int head[maxn],cnt;
bool ye[maxn];
struct edge{
int to,next;
}e[maxn];
void add(int u,int v){
e[++cnt]={v,head[u]};
head[u]=cnt;
}
void dfs(int son,int fa){
for(int i=head[son];i;i=e[i].next){
dep[e[i].to]=dep[son]+1;
dfs(e[i].to,son);
}
}
int main(){
scanf("%d",&n);
for(int i=1,x,y;i<=n;i++){
scanf("%d%d",&x,&y);
if(x==0||y==0){
ye[i]=1;
}else{
add(i,x),add(i,y);
}
}
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int del=((n-1)/2+1)/2;
dfs(1,1);
int ans=0;
for(int i=1;i<=n;i++){
if(!ye[i]) continue;
if(dep[i]<=del){
ans=max(ans,a[i]);
}
}
printf("%d\n",ans);
return 0;
}
不摆烂了,写题