二分+树dp___zxa and leaf( hdu 5682 BestCoder Round #83 )
来源:互联网 发布:下载炒股票软件 编辑:程序博客网 时间:2024/06/10 14:02
问题描述
zxa有一棵含有n个节点的无根树,包含(n−1)条无向边,点从1到n编号,定义每个点的度数为与这个点相连的边的数量,度数为1的节点被称作这棵树的叶子节点。zxa想给每个节点设置它的好看度,好看度必须为正整数。他的无根树有m(1≤m≤n)个叶子节点,其中的k(1≤k≤m)个叶子节点的好看度已经确定,zxa只需要设置其他节点的好看度。zxa很好奇,如果令每条边的难看度是这条边所连接的两个节点的好看度差值的绝对值,整棵树的难看度是所有边的难看度中的最大值,那么这棵树的难看度最小是多少,你能帮助他吗?
输入描述
第一行有一个正整数T,表示有T组数据。对于每组数据:第一行有两个正整数n和k,表示这棵树有n个节点,其中k个叶子节点的好看度已经确定。接下来(n−1)行,每行有两个互异的正整数u和v,表示节点u和节点v之间有一条无向边。接下来k行,每行有两个正整数u和w,表示节点u是叶子节点,而且它的好看度是w。每一行相邻数字之间只有一个空格。保证输入的边构成一棵树。1≤T≤10,2≤n≤5⋅104,1≤k≤n,1≤u,v≤n,1≤w≤109
输出描述
对于每组数据,输出一行,包含一个非负整数,表示这棵树的难看度最小值。
输入样例
23 21 21 32 43 96 21 21 31 42 52 63 65 9
输出样例
31
Hint
如果你需要更大的栈空间,请使用#pragma comment(linker, "/STACK:102400000,102400000")并且选择使用C++提交你的代码。
分析:
这个题目可以直接二分答案,然后对于答案用树dp去检验是否可以。
如何去检验呢?
所有节点都有一个值域。除了题目给出好感度ai的节点其值域为[ai,ai]。其余值域都初始化为[0,INF].
然后用搜索递推出所有节点的值域,如果某个节点的值域为空集那么该答案就不可以。
代码:
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#define N 50010#define INF 1000000009#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;vector<int>edge[N];int root;long long l[N], r[N];int visit[N];int n, m, k;void Init(){ for (int i = 1; i <= n; i++) { if (!visit[i]) { l[i] = 0; r[i] = INF; } }}bool dfs(int now, int pre, int dis){ for (int i = 0; i < edge[now].size(); i++) { if (edge[now][i] == pre) continue; //子节点不能等于父节点 if (!dfs(edge[now][i], now, dis)) return false; //搜索子节点 long long ll = l[edge[now][i]] - dis; long long rr = r[edge[now][i]] + dis; //得到由儿子递推过来的新值域 if (ll > r[now] || rr < l[now]) return false; //判断是否矛盾 r[now] = min(r[now], rr); l[now] = max(l[now], ll); //更新当前结点新值域 } return true;}int main(){ int t; cin >> t; while (t--) { scanf("%d%d", &n, &k); for (int i = 1; i < N; i++) edge[i].clear(); memset(visit, 0, sizeof(visit)); int u, v, w; for (int i = 0; i < n - 1; i++) { scanf("%d%d", &u, &v); edge[u].push_back(v); edge[v].push_back(u); } for (int i = 0; i < k; i++) { scanf("%d%d", &u, &w); l[u] = w; r[u] = w; visit[u] = 1; } int L = 0, R = INF, MID; while (L <= R) { Init(); MID = (L + R) >> 1; if (dfs(1, -1, MID)) R = MID - 1; else L = MID + 1; } printf("%d\n", L); } return 0;}
0 0
- 二分+树dp___zxa and leaf( hdu 5682 BestCoder Round #83 )
- BestCoder #83 1003 zxa and leaf(二分查找/BFS)
- hdu 5682 zxa and leaf 二分答案
- HDU 5682:zxa and leaf 二分
- hdu 5682 zxa and leaf (二分+搜索)
- hdu 5682 zxa and leaf(树形DP+二分)
- HDU 5682 zxa and leaf 二分 树形dp
- BestCoder Round #83 1001&&HDU-5680 zxa and set (水)
- BestCoder Round #83 1004 && HDU-5683 zxa and xor (水)
- 找规律___zxa and set(hdu 5680 BestCoder Round #83)
- 暴力____zxa and xor( hdu 5683 BestCoder Round #83 )
- HDU 5682 zxa and leaf
- HDU 5682 zxa and leaf
- BestCoder Round #83(HDU 5680)
- STL之二分查找:hdu 5178 ( BestCoder Round #31 1001 )
- BestCoder Round #83 1004 zxa and xor
- BestCoder Round #83 1001 zxa and set
- BestCoder Round #83 Problem1001 zxa and set
- 《剑指offer》-第一个只出现一次的字符位置
- WPF 启动类(窗口)移动到项目的子目录之后,无法启动程序,找不到xxx.xaml资源
- C实现复制文件
- 2016年技术源码&书籍阅读总结
- 不是人人都懂的学习要点
- 二分+树dp___zxa and leaf( hdu 5682 BestCoder Round #83 )
- leetcode 147. Insertion Sort List-链表插入排序
- Android系统横竖屏切换时候Activity的生命周期
- Android studio 中SlidingMenu的使用
- hdu 5645 DZY Loves Balls 概率
- XPath与lxml_3XPath坐标轴
- maven打包时无法识别lombok中@Data生成的get set方法
- 主线程就防止在子线程操作UI
- Java千百问_08JDK详解(003)_jdk基础类库都有什么