【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;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626652.html