NOIP模拟(20171023)T3 拆网线
来源:互联网 发布:淘宝汽车配件保证金 编辑:程序博客网 时间:2024/06/10 23:36
求用最小数量的边使得树上至少k个点被这些边覆盖
显然,一条边覆盖两个点最好。
考虑最多能有多少边能覆盖两个点,用树形dp即可
复杂度
#include<bits/stdc++.h>#define LENusing namespace std;inline int getint(){ int x=0,p=1; char c=getchar(); while(!isdigit(c)){ if(c=='-')p=-1; c=getchar(); } while(isdigit(c)){ x=(x<<3)+(x<<1)+(c^'0'); c=getchar(); } return x*p;}int dp[100005][2];struct tree{ int fa; vector<int>son;}t[100005];void dfs(int cur){ dp[cur][1]=dp[cur][0]=0; for(int i=0;i<t[cur].son.size();++i){ int v=t[cur].son[i]; dfs(v); dp[cur][0]+=max(dp[v][1],dp[v][0]); } for(int i=0;i<t[cur].son.size();++i){ int v=t[cur].son[i],x; if((x=dp[cur][0]-max(dp[v][0],dp[v][1])+dp[v][0]+1)>dp[cur][1]){ dp[cur][1]=x; } }}int main(){ int T=getint(); while(T--){ memset(dp,0,sizeof(dp)); memset(t,0,sizeof(t)); int n=getint(),k=getint(); for(int i=2;i<=n;++i){ int fa=getint(); t[fa].son.push_back(i); t[i].fa=fa; } dfs(1); int ans=max(dp[1][0],dp[1][1]); //cout<<ans<<endl; if(k<=ans*2){ cout<<(k+1)/2<<endl; } else{ cout<<ans+k-ans*2<<endl; } } return 0;}
阅读全文
0 0
- NOIP模拟(20171023)T3 拆网线
- NOIP模拟(10.23)T3 拆网线
- 【NOIP 模拟题】[T3] 约会(lca)
- NOIP模拟(10.19)T3 放盒子
- NOIP模拟(10.20)T3 裁剪表格
- NOIP模拟(10.22)T3 树
- NOIP模拟(10.24)T3 Math
- NOIP模拟(20171024)T3 数学
- NOIP模拟(20171026)T3 大逃杀
- NOIP模拟(10.26)T3 大逃杀
- NOIP模拟(10.27)T3 心灵治愈
- NOIP模拟(10.30)T3 星星
- NOIP模拟(10.31)T3 纸带
- NOIP模拟(20171030)T3 星星
- NOIP模拟(11.07)T3 图
- NOIP模拟(20171031)T3 纸带
- noip模拟11.3 T3
- [NOIP模拟] 拆网线 树形DP
- 2017年10月23日提高组T1 摆书
- iOS多线程——你要知道的GCD都在这里
- 人工智能创业,你需要知道的 6 大核心问题
- 判断整型数字是否是回文
- 浅谈 STL中的 nth_element() 使用方法
- NOIP模拟(20171023)T3 拆网线
- day09File类
- iOS11(15A372)分享下载地址
- iOS多线程——你要知道的NSOperation都在这里
- C++中的强制类型转换
- phaser
- mysql存储过程repeat循环游标基本步骤
- MySQL外键设置中的的 Cascade、NO ACTION、Restrict、SET NULL
- Ubuntu下cudnn安装