zoj 3506 Cut the Tree (树形dp)

本文介绍了一种关于子树切割的算法实现,通过递归深度优先搜索遍历树结构,并使用动态规划来求解子树中最大权值的问题。具体探讨了如何通过调整切割次数来优化树中节点间的连接,以达到全局最优解。

这道题细节很多,调了很长时间,设mx[u][j]表示以u为根的子树,切j刀后,这颗子树中与u连通的所有节点的最大权值,包括u。考虑每颗子树的决策,要么切掉,要么连上。
附用例:
4 1
-3 -2 1 1
1 2
2 3
1 4

4 2
-3 -2 1 1
1 2
2 3
1 4

5 2
1 2 3 4 5
1 2
2 3
3 4
4 5

6 2
-3 1 -2 3 4 0
1 2
1 3
2 4
3 5
3 6

6 3
-3 1 -2 3 4 0
1 2
1 3
2 4
3 5
3 6

6 4
-3 1 -2 3 4 0
1 2
1 3
2 4
3 5
3 6

6 5
-3 1 -2 3 4 0
1 2
1 3
2 4
3 5
3 6

4 2
1 2 3 4
1 2
2 3
3 4

10 4
-1 2 -3 4 -5 6 -7 8 -9 10
1 2
2 4
2 5
2 6
1 3
3 8
3 7
7 9
7 10

10 8
-1 2 -3 4 -5 6 -7 8 -9 10
1 2
2 4
2 5
2 6
1 3
3 8
3 7
7 9
7 10

ans:
-4 1
-5 1
1 12
-5 4
-5 4
-5 4
-3 4
1 7
-23 16
-16 10

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 1005
using namespace std;

vector<int>edge[N];
int weight[N],mx[N][25],mn[N][25],n,k,ansmx,ansmn;

int dfs(int u,int fa)
{
        int i,len=edge[u].size(),v,j,l,sum=0,nums;
        mn[u][0]=mx[u][0]=weight[u];
        for(i=0;i<len;i++){
                v=edge[u][i];
                if(v==fa) continue;
                if(u==2)
                u=2;
                sum+=(nums=dfs(v,u));
                for(j=min(k,sum);j>=0;j--){
                        int tmp1=-999999999,tmp2=999999999;
                        for(l=0;l<j && l<nums;l++){
                                tmp1=max(tmp1,max(mx[u][j-l-1],mx[u][j-l]+mx[v][l]));
                                tmp2=min(tmp2,min(mn[u][j-l-1],mn[u][j-l]+mn[v][l]));
                        }
                        if(l<nums && j==l) tmp1=max(tmp1,mx[u][j-l]+mx[v][l]) , tmp2=min(tmp2,mn[u][j-l]+mn[v][l]);
                        mx[u][j]=tmp1;
                        mn[u][j]=tmp2;
                }
        }
       for(j=(u!=1);j<=k && j<=n-sum-1;j++){
                ansmx=max(ansmx,mx[u][k-j]);
                ansmn=min(ansmn,mn[u][k-j]);
       }
        return sum+1;
}

int main()
{
        while(~scanf("%d%d",&n,&k)){
                memset(mx,-50,sizeof(mx));
                memset(mn,50,sizeof(mn));
                ansmx=mx[0][0]; ansmn=mn[0][0];
                int i;
                for(i=1;i<=n;i++) edge[i].clear();
                for(i=1;i<=n;i++) scanf("%d",weight+i);
                for(i=1;i<n;i++){
                        int a,b;
                        scanf("%d%d",&a,&b);
                        edge[a].push_back(b);
                        edge[b].push_back(a);
                }
                dfs(1,0);
                printf("%d %d\n",ansmn,ansmx);
        }
        return 0;
}
AI-PPT 一键生成 PPT:用户输入主题关键词,AI-PPT 可快速生成完整 PPT,涵盖标题、正文、段落结构等,还支持对话式生成,用户可在 AI 交互窗口边查看边修改。 文档导入转 PPT:支持导入 Word、Excel、PDF 等多种格式文档,自动解析文档结构,将其转换为结构清晰、排版规范的 PPT,有保持原文和智能优化两种模式。 AI-PPT 对话 实时问答:用户上传 PPT 或 PPTX 文件后,可针对演示内容进行提问,AI 实时提供解答,帮助用户快速理解内容。 多角度内容分析:对 PPT 内容进行多角度分析,提供全面视野,帮助用户更好地把握内容结构和重点。 多语言对话支持:支持多语言对话,打破语言障碍,方便不同语言背景的用户使用。 AI - 绘图 文生图:用户输入文字描述,即可生成符合语义的不同风格图像,如油画、水彩、中国画等,支持中英文双语输入。 图生图:用户上传图片并输入描述,AI - 绘图能够根据参考图和描述生成新的风格化图像,适用于需要特定风格或元素的创作需求。 图像编辑:提供如 AI 超清、AI 扩图、AI 无痕消除等功能,用户可以上传图片进行细节修改和优化,提升图片质量。 AI - 文稿 文案生成:能够根据用户需求生成多种类型的文章,如市场营销文案、技术文档、内部沟通内容等,提升文案质量和创作效率。 文章润色:对已有文章进行改善和优化,包括语言表达、逻辑连贯性、内容流畅度等方面,使文章更符合用户期望和风格。 文章续写:AI 技术理解文本语境,为用户提供新的想法、补充资料或更深层次的见解,帮助用户丰富文档内容。 AI - 医生 智能健康咨询:包括症状自查,用户输入不适症状,AI 结合病史等信息提供疾病可能性分析与初步建议;用药指导,支持查询药品适应症、禁忌症等,并预警潜在冲突;中医辨证,提供体质辨识与调理建议。 医学报告解读:用户上传体检报告
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值