zoukankan      html  css  js  c++  java
  • 【9936】二叉苹果树

    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    有一棵苹果树,如果树枝有分叉,一定是分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个。
    输出格式
    一个数,最多能留住的苹果的数量。
    样例输入
    5 2
    1 3 1
    1 4 10
    2 3 20
    3 5 20
    样例输出
    21

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=9936

    【题解】

    设f[x][y]为x节点以下保留y根树枝,最多能够留住的苹果数
    只保留x节点的一根树枝:f[x][y] = max(f[x][y],f[x’son][y-1]+a[x][x’son]);
    x节点的两根树枝都保留f[x][y] = max(f[x][y],f[x左儿子][u]+f[x右儿子][v]+a[x][x左儿子]+a[x][x右儿子]);
    这里u+v==y-2;
    题目要求最后根节点必须要保留下来;
    就是说那些脱离根节点的连通块不能作为答案;
    直接输出f[1][Q]就好,而不是f[1..n][Q]里面的最大值;

    【完整代码】

    #include <cstdio>
    #include <iostream>
    #include <cmath>
    #include <vector>
    #include <algorithm>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%I64d",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int MAXN = 110;
    
    int n,q;
    int f[MAXN][MAXN];
    vector <int> g[MAXN],w[MAXN];
    
    void dfs(int x,int fa)
    {
        int len = g[x].size(),temp = 0,l[3],cnt=0;
        rep1(i,0,len-1)
        {
            int y = g[x][i];
            if (y==fa) continue;
            dfs(y,x);
            rep1(j,1,n)
                f[x][j] = max(f[x][j],f[y][j-1]+w[x][i]);
            l[++cnt] = y;
            temp+=w[x][i];
        }
        if (cnt==2)
            rep1(i,1,n)
                rep1(j,0,i-2)
                    f[x][i] = max(f[x][i],f[l[1]][j]+f[l[2]][i-j-2]+temp);
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        cin >> n >> q;
        rep1(i,1,n-1)
        {
            int x,y,z;
            rei(x);rei(y);rei(z);
            g[x].pb(y);g[y].pb(x);
            w[x].pb(z);w[y].pb(z);
        }
        dfs(1,0);
        printf("%d
    ",f[1][q]);
        return 0;
    }
  • 相关阅读:
    数据结构与算法之PHP排序算法(快速排序)
    ThinkPHP5.0源码学习之注册错误和异常处理机制
    ThinkPHP5.0源码学习之注册自动加载
    C高级 跨平台协程库
    C中级 MariaDB Connector/C API 编程教程
    C高级 框架开发中红黑树结构
    c json实战引擎四 , 最后❤跳跃
    C基础 万能动态数组
    C基础 内存统一入口
    C基础 一个可以改变linux的函数getch
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626652.html
Copyright © 2011-2022 走看看