• 解题报告: luogu P2015


    明天就考试了,可是树形(dp)还是不会。
    题目链接:P2015 二叉苹果树
    其实就是这题的双倍经验啦。
    动态转移方程是

    [f[i][j]=max(f[i][j],f[i][i-k-1]+f[i_{son}][k]+e[i].w) ]

    这里(f[i][j])代表从以(i)为根的子树中合法留(j)个树枝的最大剩余值。

    (Code):

    #include<cmath>
    #include<cstdio> 
    #include<iostream>
    const int MAXN=105;
    using namespace std;
    typedef long long ll;
    ll f[MAXN][MAXN],c;
    int n,s,l,r,root,tot[MAXN];
    struct node
    {
    	int to,nxt;
    	ll w;
    }e[MAXN<<1];
    int head[MAXN],cnt=0;
    int deg[MAXN];
    void add(int u,int v,ll c)
    {
    	e[++cnt].to=v;
    	e[cnt].nxt=head[u];
    	e[cnt].w=c;
    	head[u]=cnt;
    }
    int dfs(int cur,int fa)
    {
    	tot[cur]=0;
    	for(int i=head[cur];i;i=e[i].nxt)
    	{
    		int j=e[i].to;
    		if(j==fa) continue;
    		int son=dfs(j,cur)+1;
    		tot[cur]+=son;
    		for(int k=tot[cur];k>=0;k--)
    		{
    			for(int v=0;k-v-1>=0&&v<=son;v++) f[cur][k]=max(f[cur][k],f[cur][k-v-1]+f[j][v]+e[i].w);
    		}
    	}
    	return tot[cur];
    }
    int main()
    {
    	scanf("%d%d",&n,&s);
    	for(int i=1;i<n;i++)
    	{
    		scanf("%d%d%lld",&l,&r,&c);
    		add(l,r,c);
    		add(r,l,c);
    		deg[l]++,deg[r]++;
    	}
    	for(int i=1;i<=n;i++) if(deg[i]==2) root=i;
    	dfs(root,0);
    	printf("%lld
    ",f[root][s]);
    	return 0;
    }
    

    好像这就是树形背包了呢。

  • 相关阅读:
    压测 正则 性能分析
    时间复杂度 根号n
    务端如何防止重复支付 架构文摘 2021-05-02
    工具大于约定和文档
    千亿级公司低代码平台的测试体系介绍
    疑惑 题解
    计算几何相关总结
    树 题解
    矩阵加速相关总结
    loj6274 数字 题解
  • 原文地址:https://www.cnblogs.com/tlx-blog/p/12430359.html
Copyright © 2020-2023  润新知