GYM-100796C-Minimax Tree【贪心】
来源:互联网 发布:泸沽湖冬天好玩吗 知乎 编辑:程序博客网 时间:2024/06/05 11:15
Bob’s new favourite toy is a rooted tree that consists of n vertices numbered from 1 to n. The number of the root vertex is 1. The tree has l leafs (the root is not considered to be a leaf). Each leaf of the tree has an integer written in it.
This birthday Bob received n - l stickers as a gift: k of them are labelled “min”, and the other n - l - k are labelled “max”. Bob has decided to place the stickers on the internal vertices of the tree, a single sticker on each internal vertex.
Once he has placed all the stickers on the tree, Bob would like to calculate a function f for each vertex v of the tree in the following fashion:
- If v is a leaf, f(v) is equal to the integer that is written in v.
- If v has a “min” sticker, f(v) is equal to the minimum value of f(u), where u is any child of v.
- If v has a “max” sticker, f(v) is equal to the maximum value of f(u), where u is any child of v.
Bob isn’t yet sure how to place his stickers on the tree, but he is interested in the value of f in the root vertex. Given the tree and the stickers, help Bob calculate the minimum and the maximum possible value of f(1)!
Input
The first line contains two space-separated integers n and k (2 ≤ n ≤ 105, 0 ≤ k ≤ n). The second line contains n - 1 space-separated integer numbers p2, p3, …, pn (1 ≤ pi ≤ n). The number pi denotes the parent of the vertex numbered i. The third line contains n space-separated integer numbers a1, a2, …, an (0 ≤ ai ≤ 109). If the vertex i is a leaf, then ai is the number written in that vertex. Otherwise ai will be equal to 0.
It is guaranteed that the given graph will be a tree. It is guaranteed that k + l ≤ n.
Output
In a single line output two integers separated by a space — the minimum and the maximum possible value of f(1).
input
6 1
1 1 2 2 3
0 0 0 1 3 2
output
2 3
题目链接:GYM-100796C
题目大意:给出一棵树,根节点为1.只有叶子节点(有L个)有值,其余节点分为两类
1. min 节点: 当前节点的f值为孩子节点的f值最小的那个2. max 节点: 当前节点的f值为孩子节点的f值最大的那个
有k个min节点,剩余的n-k-L个节点则为max节点,问1节点的f值最大和最小为多少?
题目思路:最小节点值为例:
1.将树全部取孩子节点最大值建好2.从最小值开始取3.如果这个最小值能推到根节点,一路上都取最小值(则为答案)
需要注意的是:如果当前这个节点取最小值后为3。其余节点跟他一样大,那他的父节点不用取最小值。
最大值反着来即可。
以下是代码:
#include <iostream>#include <iomanip>#include <fstream>#include <sstream>#include <cmath>#include <cstdio>#include <cstring>#include <cctype>#include <algorithm>#include <functional>#include <numeric>#include <string>#include <set>#include <map>#include <stack>#include <vector>#include <queue>#include <deque>#include <list>using namespace std;vector <int> e[100005];int a[100005];int a2[100005];int fa[100005];void dfs(int cur){ int len = e[cur].size(); if (len == 0) { return; } int ret = 0; for (int i = 0; i < len; i++) { int v = e[cur][i]; dfs(v); ret = max(ret, a[v]); } a[cur] = ret;}void dfs2(int cur){ int len = e[cur].size(); if (len == 0) { return; } int ret = 0; for (int i = 0; i < len; i++) { int v = e[cur][i]; dfs(v); ret = min(ret, a2[v]); } a2[cur] = ret;}struct node{ int id; int val;}b[100005];bool cmp(node x, node y){ return x.val < y.val;}bool cmp2(node x, node y){ return x.val > y.val;}int main(){ int n,k; scanf("%d%d",&n,&k); for (int i = 0; i < n - 1; i++) { int num; scanf("%d",&num); e[num].push_back(i + 2); fa[i+2] = num; } int lll = 0; for (int i = 1; i <= n; i++) { scanf("%d",&b[i].val); b[i].id = i; a[i] = b[i].val; a2[i] = b[i].val; if (b[i].val != 0) lll++; } sort(b + 1, b + n + 1, cmp); dfs(1); int min_ans = 1e9+1, max_ans = 0; for (int i = 1; i <= n; i++) { if (b[i].val != 0) { int p = fa[b[i].id]; int w = a[b[i].id]; int cnt = 0; while(1) { int len = e[p].size(); if (len > 1) { int ret = 0; for (int j = 0; j < len; j++) { int v = e[p][j]; if (a[v] > w) { cnt++; break; } } } if (p == 1) break; p = fa[p]; } if (cnt <= k) { min_ans = b[i].val; break; } } } sort(b + 1, b + n + 1, cmp2); dfs2(1); for (int i = 1; i <= n; i++) { if (b[i].val != 0) { int p = fa[b[i].id]; int w = a2[b[i].id]; int cnt = 0; while(1) { int len = e[p].size(); if (len > 1) { int ret = 0; for (int j = 0; j < len; j++) { int v = e[p][j]; if (a2[v] < w) { cnt++; break; } } } if (p == 1) break; p = fa[p]; } if (cnt <= (n - k - lll)) { max_ans = b[i].val; break; } } } printf("%d %d\n",min_ans,max_ans); return 0;}
- GYM-100796C-Minimax Tree【贪心】
- GYM 100796C Minimax Tree
- Gym 100796C Minimax Tree
- 2015-2016 ACM ICPC Baltic Selection Contest C Minimax Tree
- GYM 100712 C.Street Lamps(贪心)
- MiniMax
- Codeforces Gym 100803C Shopping 贪心好题
- Gym 100341C AVL TREE(NTT快速数论变换)
- Gym 100712E 贪心
- CodeForces - 338C Divisor Tree 【贪心】
- Gym - 101102C C. Bored Judge 线段树+贪心+反向推
- Principles of Computing (Part 2) -- week 3 (Tree, Lambda, Minimax)
- Gym - 100338E Numbers 贪心
- Gym 100231D Balloons 贪心
- Gym 100803A(贪心)
- Gym-101257H Card【贪心】
- 【Codeforces Gym 100187F 】+ 贪心
- codeforces-gym-100187-F【贪心】
- 2.docker的使用之镜像的操作
- Git 在团队中的最佳实践--如何正确使用Git Flow
- ViewPager版本二
- ViewPager+小圆点
- 进程之task_struct
- GYM-100796C-Minimax Tree【贪心】
- 为JQuery扩展一个对象方法
- HAUTOJ 1266: 最大子段和 河工大校赛DP
- DWR3.0(1)
- HDU1494 动态规划
- JAVA的JDBC的简单练习项目,一个简单的饭卡系统
- 从网络获取图片资源缓存到本地,第二次进入直接从本地加载。
- 安卓获取渠道名渠道id Android获取设备唯一标识的终极解决方法,防止安卓7.0时崩溃问题
- <Effective Mordern C++>笔记:Item 2:Understand auto type deduction.