当前位置 博文首页 > Keven_11的博客:C++题解:奇怪的花卉

    Keven_11的博客:C++题解:奇怪的花卉

    作者:[db:作者] 时间:2021-08-18 15:49

    ????目录

    题目?

    题解


    题目?

    小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题。一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题。于是当日课后,小明就向老师提出了这个问题:

    一株奇怪的花卉,上面共连有?N?朵花,共有?N?1?条枝干将花儿连在一起,并且未修剪时每朵花都不是孤立的。每朵花都有一个“美丽指数”,该数越大说明这朵花越漂亮,也有“美丽指数”为负数的,说明这朵花看着都让人恶心。所谓“修剪”,意为:去掉其中的一条枝条,这样一株花就成了两株,扔掉其中一株。经过一系列“修剪“之后,还剩下最后一株花(也可能是一朵)。老师的任务就是:通过一系列“修剪”(也可以什么“修剪”都不进行),使剩下的那株(那朵)花卉上所有花朵的“美丽指数”之和最大。

    老师想了一会儿,给出了正解。小明见问题被轻易攻破,相当不爽,于是又拿来问你。

    输入格式

    第一行一个整数 N?(1≤N≤16000),表示原始的那株花卉上共?N?朵花。

    第二行有?N?个整数,第?i?个整数 ai??(?10^4≤ai?≤10^4)表示第?ii?朵花的美丽指数。

    接下来 N?1?行每行两个整数?a,b,表示存在一条连接第?a?朵花和第?b?朵花的枝条。

    输出格式

    一个数,表示一系列“修剪”之后所能得到的“美丽指数”之和的最大值。

    输出时每行末尾的多余空格,不影响答案正确性

    要求使用「文件输入输出」的方式解题,输入文件为?flower.in,输出文件为?flower.out

    样例输入

    7
    -1 -1 -1 1 1 1 0
    1 4
    2 5
    3 6
    4 7
    5 7
    6 7

    样例输出

    3

    题解:

    知识点:树形DP

    分析:最基本的树形 dp 问题,任选一个结点作为根进行遍历。dp[u]?表示包含?u?这个节点的子树的美丽指数最大值,遍历?u?的所有儿子?v?后,如果?dp[v]?为正值就加入到当前子树?u?中。此处用链式前向星来存储图,也可用vector,反正都是邻接表

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=32000;
    int a[N],e[N],ne[N],h[N],idx,dp[N],ans=-0x7fffffff;
    void init(){//链式前向星
        memset(h,-1,sizeof(h));
        idx=0;
    }
    void add(int x,int y){//链式前向星
        e[idx]=y;
        ne[idx]=h[x];
        h[x]=idx++;
    }
    int dfs(int u,int fa){//树形DP
        dp[u]=a[u];
        for (int i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if (j!=fa && dfs(j,u)>0){//1.此节点不等于其父节点 2.其子树价值大于0
                dp[u]+=dp[j];//不说了,易想
            }
        }
        ans=max(dp[u],ans);//ans存答案
        return dp[u];
    }
    int main(){
        freopen("flower.in","r",stdin);
        freopen("flower.out","w",stdout);
        init();
        int n,x,y;
        scanf("%d",&n);
        for (int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        for (int i=0;i<n-1;i++){
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs(1,0);
        printf("%d",ans);
        return 0;
    }

    cs
    下一篇:没有了