【JZOJ4814】【NOIP2016提高A组五校联考2】tree
来源:互联网 发布:js中的层级选择器 编辑:程序博客网 时间:2024/06/05 07:37
题目描述
给一棵n 个结点的有根树,结点由1 到n 标号,根结点的标号为1。每个结点上有一个物品,第i 个结点上的物品价值为vi。
你需要从所有结点中选出若干个结点,使得对于任意一个被选中的结点,其到根的路径上所有的点都被选中,并且选中结点的个数不能超过给定的上限lim。在此前提下,你需要最大化选中结点上物品的价值之和。
求这个最大的价值之和。
输入
第一行为两个整数n; lim
接下来n 行,第i 行包含一个整数vi,表示结点i 上物品的价值。
接下来n- 1 行,每行包含两个整数u; v, 描述一条连接u; v 结点的树边。
输出
输出一行答案。
样例输入
6 4
-5
4
-6
6
9
6
3 2
3 1
2 4
2 5
1 6
样例输出
2
数据范围
对于前20% 的数据,1<=n; lim<=10
对于前60% 的数据,1<=n; lim<=100
对于100% 的数据,1<=n; lim<=3000; |vi| <=10^5 数据有梯度,保证给出的是合法的树。
解法
把条件转化,设原树有根,如果一个结点不选,那么以其为根的子树都不能选。
显然我们可以把树转化成dfs序列。
设f[i][j]为前i个数中,选了j个数的最大答案。
时间复杂度为
代码
#include<iostream>#include<stdio.h>#include<math.h>#include<string.h>#include<algorithm>#define ll long long#define ln(x,y) int(log(x)/log(y))#define sqr(x) ((x)*(x))using namespace std;const char* fin="tree.in";const char* fout="tree.out";const int inf=0x7fffffff;const int maxn=3007,maxm=maxn*2,maxa=100000;int n,m,i,j,k,tot,ans=0;int a[maxn],fi[maxn],ne[maxm],la[maxm];int f[maxn][maxn],de[maxn];int c[maxn],low[maxn],dfn[maxn];void add_line(int a,int b){ tot++; ne[tot]=fi[a]; la[tot]=b; fi[a]=tot;}void dfs(int v,int from){ int i,j,k; c[++c[0]]=v; dfn[v]=c[0]; for (k=fi[v];k;k=ne[k]) if (la[k]!=from) { dfs(la[k],v); } low[dfn[v]]=c[0];}int main(){ freopen(fin,"r",stdin); freopen(fout,"w",stdout); scanf("%d%d",&n,&m); memset(f,128,sizeof(f)); for (i=1;i<=n;i++) scanf("%d",&a[i]); for (i=1;i<n;i++){ scanf("%d%d",&j,&k); add_line(j,k); add_line(k,j); } dfs(1,0); f[0][0]=0; for (i=0;i<n;i++){ for (j=0;j<m;j++){ if (f[i][j]<-2000000000) continue; f[i+1][j+1]=max(f[i+1][j+1],f[i][j]+a[c[i+1]]); f[low[i+1]][j]=max(f[low[i+1]][j],f[i][j]); } } for (i=1;i<=n;i++) for (j=0;j<=m;j++) ans=max(ans,f[i][j]); printf("%d",ans); return 0;}
启发
尝试把条件以另一个角度看待,那么新的方法就会出现。
当要处理子树问题时,不妨把原树转化为dfs序列。
1 0
- 【JZOJ4814】【NOIP2016提高A组五校联考2】tree
- JZOJ4814. 【NOIP2016提高A组五校联考2】tree
- 【NOIP2016提高A组五校联考2】tree
- 【NOIP2016提高A组五校联考2】tree
- 【NOIP2016提高A组五校联考2】tree
- tree 【NOIP2016提高A组五校联考2】
- JZOJ 4814. 【NOIP2016提高A组五校联考2】tree
- 【jzoj 4814】【NOIP2016提高A组五校联考2】tree
- JZOJ 4814 【NOIP2016提高A组五校联考2】tree
- NOIP2016提高A组五校联考2总结
- 【NOIP2016提高A组五校联考2】string
- 【NOIP2016提高A组五校联考2】running
- NOIP2016提高A组五校联考2总结
- 【NOIP2016提高A组五校联考2】string
- 【NOIP2016提高A组五校联考2】string
- 【NOIP2016提高A组五校联考2】running
- JZOJ4813. 【NOIP2016提高A组五校联考2】
- running 【NOIP2016提高A组五校联考2】
- Leetcode007--将字符串转换成整形
- Xamarin Android Fragment的两种加载方式
- hdu ---2005做题笔记(c++)
- 欢迎使用CSDN-markdown编辑器
- “光”的历史(一)
- 【JZOJ4814】【NOIP2016提高A组五校联考2】tree
- UVa1225 Digit Counting
- caffe-reduction layer
- HDU 5920 Ugly Problem(大数减法 模拟)
- Java基础--集合List-LinkedList
- hdu ---2006做题笔记(c++)
- opencv技术访问图像中的像素
- C# WebBrowser强制在本窗口打开,禁止在新窗口打开
- Makefile 中:= ?= += =的区别