• 【洛谷 2015】二叉苹果树


    题目描述

    有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)

    这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。

    我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树

    2   5
      / 
      3   4
        /
        1
    

    现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。

    给定需要保留的树枝数量,求出最多能留住多少苹果。

    输入格式

    第1行2个数,N和Q(1<=Q<= N,1<N<=100)。

    N表示树的结点数,Q表示要保留的树枝数量。接下来N-1行描述树枝的信息。

    每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。

    每根树枝上的苹果不超过30000个。

    输出格式

    一个数,最多能留住的苹果的数量。

    输入输出样例

    输入 #1
    5 2
    1 3 1
    1 4 10
    2 3 20
    3 5 20
    
    输出 #1
    21

    题解:树形DP,代码里写了注释哦,详见一本通哈哈。
    ps:为什么首先要m++。因为我们计算按点计算,而m是边。
    所以保留m+1个节点(一开始没注意,结果答案老是10……)
    #include<iostream>
    #include<algorithm>
    #include<queue>  
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    using namespace std;
    const int N=102;
    int x,y,z,n,m,f[N][N],map[N][N],a[N],l[N],r[N];
    void Build(int u){
        for(int i=1;i<=n;i++){
            if(map[u][i]>=0){
                l[u]=i; a[i]=map[u][i];
                map[u][i]=-1; map[i][u]=-1;
                Build(i); break;
            }
        }
        for(int i=1;i<=n;i++){
            if(map[u][i]>=0){
                r[u]=i; a[i]=map[u][i];
                map[u][i]=-1; map[i][u]=-1;
                Build(i); break;
            }
        }
    }
    
    int dfs(int i,int j){
        //f[i][j]表示以i为根的树上保留j个节点的最大权值和 
        if(j==0) return 0;
        if(l[i]==0 && r[i]==0) return a[i];//叶节点
        if(f[i][j]>0) return f[i][j];//已计算过
        for(int k=0;k<=j-1;k++)
            f[i][j]=max(f[i][j],dfs(l[i],k)+dfs(r[i],j-k-1)+a[i]);
        //左子树保留k个节点,右子树保留j-k-1个节点 
        return f[i][j]; 
    }
    
    int main(){
        freopen("2015.in","r",stdin);
        freopen("2015.out","w",stdout);
        scanf("%d %d",&n,&m);
        memset(map,-1,sizeof(map));
        for(int i=1;i<n;i++){
            scanf("%d %d %d",&x,&y,&z);
            map[x][y]=z; map[y][x]=z;
        }
        Build(1); m++;
        cout<<dfs(1,m);
        return 0;
    }
  • 相关阅读:
    java2: HttpClient,实现登录,请求等操作,session保持
    bat使用1
    java4: 读取配置文件
    HTML+CSS学习笔记(一)
    第1章:JavaScript简介
    第2章:在HTML中使用JavaScript
    HTML+CSS学习笔记(二)
    ASP.NET防止页面刷新的方法
    上下左右无空隙不间断图片连续滚动代码
    SQL Server2005新加的功能排名函数
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11329603.html
Copyright © 2020-2023  润新知