【每日一题】黑白树

黑白树

https://ac.nowcoder.com/acm/problem/13249

Solution

由题意可知叶子节点必定要染色。对于其他节点:

  • 若此节点的已经染色的子节点中,可以将它覆盖,那么不需要染色,并借助这个点能覆盖的范围更新最大范围。
  • 若此节点的已经染色的子节点中,不能将它覆盖,那么需要将其子节点中范围最大的点染色,并更新最大范围。

可以发现这是一个由子节点向父节点更新的过程,所以可以使用 。每次贪心地更新能覆盖的最大距离,不能覆盖就进行染色。

时间复杂度:

Code

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1e5+10;
struct edge{
    int t;
    int v;
}e[maxn<<1];
int ans,tot,n,k[maxn],hd[maxn];
void add(int x,int y){
    tot++;
    e[tot].t=hd[x];
    e[tot].v=y;
    hd[x]=tot;
}
int dfs(int u,int fa){
    int sum=0;
    for(int i=hd[u];i!=0;i=e[i].t)
        if(e[i].v!=fa)
            sum=max(sum,dfs(e[i].v,u));
    if(!sum){
        ans++;
        return k[u]-1;
    }
    k[fa]=max(k[fa],k[u]-1);//将所有子节点能覆盖的最大范围更新到父节点上,方便染色后返回
    return sum-1;
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n;
    int x;
    for(int i=2;i<=n;i++){
        cin>>x;
        add(x,i);
        add(i,x);
    }
    for(int i=1;i<=n;i++)
        cin>>k[i];
    dfs(1,0);
    cout<<ans;
    return 0;
}
全部评论

相关推荐

一个菜鸡罢了:哥们,感觉你的简历还是有点问题的,我提几点建议,看看能不能提供一点帮助 1. ”新余学院“别加粗,课程不清楚是否有必要写,感觉版面不如拿来写一下做过的事情,教育经历是你的弱势就尽量少写 2. “干部及社团经历”和“自我评价”删掉 3. 论文后面的“录用”和“小修”啥的都删掉,默认全录用,问了再说,反正小修毕业前肯定能发出来 4. 工作经验和研究成果没有体现你的个人贡献,着重包装一下个人贡献
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务