8VC Venture Cup 2016 - Final Round D. Preorder Test 二分,树形dp
2017-03-27 15:16
148 查看
题目链接:http://codeforces.com/contest/627/problem/D
题意:给你一棵树,带点权,让你找到一个dfs搜索的顺序中,至少大于k个点,且这k个点的最小值最大,对于DFS序,你可以随意安排子树的访问顺序
解法: 最小值最大,或者最大值最小这种题首先考虑二分,二分答案,然后我们进行check,我们把大于mid的点标为1,然后我们就可以开始树dp了。显然对于某个点来说,除了他儿子那棵子树的所有点都是满足条件的,否则他最多选择两个儿子的不完整子树。然后我们通过这个进行dp就好了,记录最大值和次大值。对了,还得check一下他的父亲,看看这个点是否能够往上延展。
题意:给你一棵树,带点权,让你找到一个dfs搜索的顺序中,至少大于k个点,且这k个点的最小值最大,对于DFS序,你可以随意安排子树的访问顺序
解法: 最小值最大,或者最大值最小这种题首先考虑二分,二分答案,然后我们进行check,我们把大于mid的点标为1,然后我们就可以开始树dp了。显然对于某个点来说,除了他儿子那棵子树的所有点都是满足条件的,否则他最多选择两个儿子的不完整子树。然后我们通过这个进行dp就好了,记录最大值和次大值。对了,还得check一下他的父亲,看看这个点是否能够往上延展。
//CF 627D //树形DP+二分答案 #include <bits/stdc++.h> using namespace std; const int maxn = 2e5+7; int n, k; int a[maxn], w[maxn], sz[maxn], up[maxn], dp[maxn]; //dp[x]代表的是节点x能得到的最大点数 //up[x]代表的是节点x能否像他的父亲延伸 vector <int> E[maxn]; int flag; void dfs1(int x, int fa, int m){ sz[x] = 1; for(int i = 0; i < E[x].size(); i++){ int v = E[x][i]; if(v == fa) continue; dfs1(v, x, m); sz[x] += sz[v]; w[x] += w[v]; } } void dfs2(int x, int fa, int m) { int Max1 = 0, Max2 = 0, tot = 0;//记录了最大值,次大值,和全部满足的子树的sz和 for(int i = 0; i < E[x].size(); i++){ int v = E[x][i]; if(v == fa) continue; if(w[x] - w[v] == sz[x] - sz[v] && up[x]) up[v] = 1; dfs2(v, x, m); if(a[v] < m) continue; if(sz[v] == w[v]){ tot += sz[v]; } else{ if(dp[v] > Max1) Max2 = Max1, Max1 = dp[v]; else if(dp[v] > Max2) Max2 = dp[v]; } } if(a[x] < m) return; if(tot + Max1 + Max2 + up[x]*(n - sz[x])+1 >= k) flag = 1; dp[x] = tot + Max1 + 1; } int check(int x){ for(int i = 1; i <= n; i++) dp[i] = up[i] = 0; for(int i = 1; i <= n; i++){ if(a[i] >= x) w[i] = 1; else w[i] = 0; } flag = 0; dfs1(1, -1, x); up[1] = w[1]; dfs2(1, -1, x); return flag; } void input(){ scanf("%d%d", &n, &k); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i < n; i++){ int x, y; scanf("%d%d", &x, &y); E[x].push_back(y); E[y].push_back(x); } } void work(){ int l = 0, r = 1e6+6, ans; while(l <= r){ int mid = (l + r) / 2; if(check(mid)) l = mid + 1, ans = mid; else r = mid - 1; } printf("%d\n", ans); } int main() { input(); work(); return 0; }
相关文章推荐
- 8VC Venture Cup 2016 - Final Round D. Preorder Test 二分 树形dp
- 8VC Venture Cup 2016 - Final Round C. Package Delivery 优先队列
- bzoj 4753: [Jsoi2016]最佳团体 二分答案+树形dp
- 8VC Venture Cup 2016 - Elimination Round F. Group Projects dp
- Codeforces 8VC Venture Cup 2016 - Elimination Round F. Group Projects 差分DP*****
- 【BZOJ4753】【JSOI2016】最佳团体(树形dp+二分)
- 8VC Venture Cup 2016 - Elimination Round F. Group Projects(DP)
- [杂题] Codeforces 627F 8VC Venture Cup 2016 - Final Round F. Island Puzzle
- [coci2015-2016 coii] torrent【树形dp 二分】
- AIM Tech Round 3 (Div. 2) E. Centroids (树形dp)
- Wunder Fund Round 2016 D. Hamiltonian Spanning Tree(贪心+dp)★ ★ ★
- Codeforces Round #202 (Div. 1) (树形dp, dp)
- Google APAC test 2015 Round B Problem D-Parentheses Order
- NOIP模拟题 2016.10.18 [二分答案] [从上到下的树形DP] [链表翻转]
- 2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest Problem J 【二分+DP+单调队列】
- 【Codeforces Round 263 (Div 2)D】【树形DP】Appleman and Tree 树上割k个黑点为k块的方案数
- (CROC 2016 - Elimination Round (Rated Unofficial Edition))D. Robot Rapping Results Report(二分+拓扑排序)
- E. Vladik and cards Codeforces Round #384 (Div. 2) 好题 二分+(贪心+状态压缩DP)判断
- 两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race
- HDU 3586 Information Disturbing 树形DP+二分