zoukankan      html  css  js  c++  java
  • Codeforces 1153D Serval and Rooted Tree (简单树形DP)

    <题目链接>

    题目大意:

    Serval拥有的有根树有n个节点,节点1是根。 Serval会将一些数字写入树的所有节点。但是,有一些限制。除叶子之外的每个节点都有一个写入操作的最大值或最小值,表示该节点中的数字应分别等于其子节点中所有数字的最大值或最小值。

    假设树中有k个叶子。 Serval希望将整数1,2,...,k放到k个叶子上(每个数字应该只使用一次)。他喜欢大的数字,因此他希望最大化根的数字。作为他最好的朋友,你能帮助他吗?

    解题分析:

    不难想到,本题就是转化成求在满足题目求的情况下,传递到根节点的最少叶子节点个数。因为叶子节点的值是由我们自己够构造,所以我们只需要将那些能够传递到根节点的叶子节点,从大到小赋值,就能够让根节点的值最大,且它的最大值为ans-num+1(ans为叶子节点个数,num为传递到根节点的叶子节点个数)。

    #include <bits/stdc++.h>
    using namespace std;
    
    template<typename T>
    inline void read(T&x){
        x=0;int f=1;char c=getchar();
        while(c<'0' || c>'9'){ if(c=='-')f=-1;c=getchar(); }
        while(c>='0' && c<='9'){ x=x*10+c-'0';c=getchar(); }
        x*=f;
    }
    
    const int N = 3e5+5;
    int val[N],num[N],ans=0;
    vector<int>G[N];
    
    void dfs(int u){
        if(G[u].size()==0){ num[u]=1;ans++;return; }
        int tmp=0;
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];
            dfs(v);
            tmp+=num[v];     //得到所有子树的所有叶子节点个数
            if(val[u]==1)num[u]=min(num[u],num[v]);  //如果是max的话,要使传递到根节点的叶子个数最少,只需要选某颗子树中最少的叶子个数
            else num[u]=max(num[u],tmp);    //如果是min的话,别无选择,只能选子树中叶子节点最多的值
        }
    }
    
    int main(){
        int n;read(n);
        for(int i=1;i<=n;i++){
            read(val[i]);
            if(val[i]==1)num[i]=1e9;
            else num[i]=0;
        }
        for(int i=2;i<=n;i++){
            int u;read(u);
            G[u].push_back(i);
        }
        dfs(1);
        printf("%d
    ",ans-num[1]+1);     
    }
  • 相关阅读:
    Netty与Spring Boot的整合
    Activiti 5.22.0 之自由驳回任务实现(亲测)
    学习机器学习前你应该要知道的一些事
    机器学习中调参的基本思想
    机器学习和深度学习区别的简要概述
    SKlearn中分类决策树的重要参数详解
    世界第二大软件国家如何看待人工智能、机器学习和大数据
    sklearn中的数据预处理和特征工程
    人工智能革命:人类永生还是灭亡(下)
    人工智能革命:人类永生还是灭亡(中)
  • 原文地址:https://www.cnblogs.com/00isok/p/10705602.html
Copyright © 2011-2022 走看看