zoukankan      html  css  js  c++  java
  • P2015 二叉苹果树

    ----------------

    链接:Miku

    ----------------

    这道题的dp还是先更新子节点,在更新父节点,不过问题就是怎样更新他们

    我们定义ff[i][j]为第i个节点字数上共保留j条边的情况下最多的苹果数,对于每一个点,他保留的边必然是他直接保留的之前保留的边和他当前儿子保留的边的值的和加上这一条边的

    边权,即ff[u][i]=max(ff[u][i],f[u][ij1]+ff[v][j]+e[i].w)( 1imin(q,son[u]),0jmin(son[v],i1) )

    然后不断递归更新即可

    ----------------

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define ll long long
    const int maxn=105;
    using namespace std;
    int n,m,ff[maxn][maxn];
    struct b{
        int to;
        int ne;
        int w;    
    }e[maxn*2];
    int p;
    int head[maxn];
    void add(int f,int to,int w){
        p++;
        e[p].ne=head[f];
        e[p].to=to;
        e[p].w=w;
        head[f]=p;
    }
    int x,y,z;
    int son[maxn];
    void dfs(int now,int f){
        for(int i=head[now];i;i=e[i].ne){
            int v=e[i].to;
                if(v==f) continue;
            dfs(v,now);
            son[now]+=son[v]+1;
            for(int j=min(son[now],m);j;--j ){//我们就能取这些了
                for(int k=min(son[v],j-1);k>=0;k--){//考虑一下怎么分配要保留的边
                    ff[now][j]=max(ff[now][j],ff[now][j-k-1]+ff[v][k]+e[i].w);//记得减一,不然我们就和这个v断开了联系
                }
            }
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<n;++i){
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        dfs(1,-1);//根节点是谁不重要
        printf("%d",ff[1][m]);
        return 0;
    }
    Ac
  • 相关阅读:
    Linux -- nginx
    Linux--虚拟环境
    Linux用户权限指令, 定时任务等指令
    Linux的基础命令, django的安装与使用
    .net与Java的WebService互调
    C#中的动态特性
    LINQ之路(3):LINQ扩展
    LINQ之路(2):LINQ to SQL本质
    LINQ之路(1):LINQ基础
    LINQ之路系列文章导读
  • 原文地址:https://www.cnblogs.com/For-Miku/p/12219622.html
Copyright © 2011-2022 走看看