zoukankan      html  css  js  c++  java
  • CF1153D Serval and Rooted Tree(树形DP)

      题目链接:

    https://www.luogu.org/problemnew/show/CF1153D

    (cf崩了,贴了个落谷的)

    题目大意:给你n个点,然后n-1条边,构成一棵树,每个点是子节点的最大值或最小值,将叶子节点填上整数(1~k,k为叶子节点的个数),使这棵树的根最大。

    具体思路:对于每一个非叶子节点,假设他的值是x,如果这个点是取max,那么就要求这个节点的子节点中至少有一个是等于x的,其他都是小于x的。如果这个点是取min,那么就要求这个节点的子节点的值都是大于等于x的。然后再继续分析,我们把当前的节点赋值 为他的子树中叶子节点的个数,那么当这个节点为取max的时候,我们就相当于他的所有子节点中取一个最大的就可以了。也就是相当于从子树中取一个最小消耗量。当为min的时候,当前节点的消耗量为他的所有子节点的消耗量之和。然后根节点的最大数就变成了k-num[1]+1.num[1]为根节点的消耗量。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define inf 0x3f3f3f3f
     4 # define ll long long
     5 const int maxn = 3e5+100;
     6 int col[maxn];
     7 vector<int>Edge[maxn];
     8 int tot=0;
     9 int num[maxn];
    10 void  dfs(int u)
    11 {
    12     if(Edge[u].size()==0)
    13     {
    14 
    15         tot++;
    16         num[u]=1;
    17         return ;
    18     }
    19     if(col[u])
    20         num[u]=inf;
    21     else
    22         num[u]=0;
    23     for(int i=0; i<Edge[u].size(); i++)
    24     {
    25         int to=Edge[u][i];
    26         dfs(to);
    27         if(col[u])
    28             num[u]=min(num[to],num[u]);
    29         else
    30             num[u]+=num[to];
    31     }
    32     return ;
    33 }
    34 int main()
    35 {
    36     int n;
    37     scanf("%d",&n);
    38     for(int i=1; i<=n; i++)
    39         scanf("%d",&col[i]);
    40     int tmp;
    41     for(int i=2; i<=n; i++)
    42     {
    43         scanf("%d",&tmp);
    44         Edge[tmp].push_back(i);
    45     }
    46     dfs(1);
    47     printf("%d
    ",tot-num[1]+1);
    48     return 0;
    49 }
  • 相关阅读:
    Web前端工程师技能列表
    CSS框架的相关汇总(CSS Frameworks)
    一个有趣的发现
    (转丁学)Firefox2的一个bug和脑子进了水的IE
    深入语义:列表Tag(ul/ol)和表格Tag(table)的抉择
    css命名简单框架
    腾讯的三栏布局考题
    土豆网前端概况
    伪绝对定位(译)
    右下角浮动广告代码DEMO
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10744268.html
Copyright © 2011-2022 走看看