SGU 507 Treediff 启发式合并
来源:互联网 发布:淘宝购物车怎么扩容 编辑:程序博客网 时间:2024/06/06 14:12
Andrew has just made a breakthrough in complexity theory: he thinks that he can prove P=NP if he can get a data structure which allows to perform the following operation quickly. Naturally, you should help him complete his brilliant research. Consider a rooted tree with integers written in the leaves. For each internal (non-leaf) node v of the tree you must compute the minimum absolute difference between all pairs of numbers written in the leaves of the subtree rooted at v.
Input
The first line of the input file contains two integers n and m — overall number of nodes in the tree and number of leaves in the tree respectively. . All nodes are numbered from 1 to n. Node number 1 is always the root of the tree. Each of the other nodes has a unique parent in the tree. Each of the next n - 1 lines of the input file contains one integer — the number of the parent node for nodes 2, 3,…, n respectively. Each of the last m lines of the input file contains one integer ranging from to — the value of the corresponding leaf. Leaves of the tree have numbers from n - m + 1 to n.
Output
Output one line with n - m integers: for each internal node of the tree output the minimum absolute difference between pairs of values written in the leaves of its subtree. If there is only one leaf in the subtree of some internal node, output number 2 31 - 1 for that node. Output the answers for the nodes in order from node number 1 to n - m.
Example(s)
sample input
5 4
1
1
1
1
1
4
7
9
sample output
2
sample input
5 4
1
1
1
1
1
4
7
10
sample output
3
sample input
7 4
1
2
1
2
3
3
2
10
7
15
sample output
3 3 8
sample input
2 1
1
100
sample output
2147483647
只有叶节点存储数据,比较每个子树下的所有叶节点之间最小差值,启发式合并。
由于比较差值要保留所有子节点,每次合并要把数据上传到父节点,用set保存,大集合赋给父节点,小集合再合并进大集合节省时间。
对于每个父节点的最值,默认为INF,对应只有一个子节点没有对比的情况。
值的比较:合并前各个子树的最值,合并时元素插入集合与相邻元素的差。
启发式合并适用于需要存储所以子节点的情况。
#include <iostream>#include <stdio.h>#include <map>#include <set>#include <queue>#include <algorithm>#include <math.h>#include <string.h>#include <iterator>#include <vector>using namespace std;typedef long long ll;int mo[4][2]={0,1,1,0,0,-1,-1,0};const int MAXN=0x3f3f3f3f;const int sz=100005;const int INF=2147483647;int n,m;int v[sz];//节点的值vector<int> son[sz];//直接连接的子节点set<int> child[sz];//子树的所有子节点set<int>::iterator pre,si,suc;int mer(set<int>& x,set<int> &y){ if(x.size()<y.size()) swap(x,y);//把大集合赋予给父节点 int t=INF;//子树没有元素时没有比较,返回INF,只有一个元素时INF一直保留 for(si=y.begin();si!=y.end();si++){//小集合取数 pre=suc=x.lower_bound(*si);//最小的大于等于它的数的位置 if(pre!=x.begin()) pre--;//左边的数 if(pre!=x.end()) t=min(t,abs(*si-*pre)); if(suc!=x.end()) t=min(t,abs(*si-*suc)); //新元素与左右元素比较,更新最小差值 x.insert(*si); } return t;}void dfs(int u){ if(!son[u].size()){//若为叶节点 child[u].insert(v[u]);//数据存入集合 v[u]=INF;//存答案 return; } v[u]=INF; for(int i=0;i<son[u].size();i++){ int t=son[u][i]; dfs(t); v[u]=min(v[u],v[t]); //合并前最小差值值比较 v[u]=min(v[u],mer(child[u],child[t])); //子树合并时,小集合插入大集合,每个元素产生的新差值作比较 }}int main(){ int k; //freopen("r.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++){ son[i].clear(); child[i].clear(); } for(int i=2;i<=n;i++){ scanf("%d",&k); son[k].push_back(i); } for(int i=n-m+1;i<=n;i++){ scanf("%d",&v[i]); } dfs(1); for(int i=1;i<=n-m;i++){ printf("%d ",v[i]); } printf("\n"); } return 0;}
- SGU 507 Treediff <启发式合并>
- SGU 507 Treediff 启发式合并
- SGU 507 Treediff (线段树合并)
- sgu 507 (启发式合并)
- SGU 507 Treediff(平衡树)
- 启发式合并
- bzoj 1438(启发式合并)
- 树上启发式合并
- BZOJ2733 永无乡 [启发式合并]
- Hdu 6133 启发式合并
- map + 启发式合并
- 树状数组+启发式合并
- 启发式合并&线段树合并&treap合并
- 伸展树的启发式合并
- hdu 4680 splay,启发式合并
- bzoj 2733(splay启发式合并)
- bzoj3123 【SDOI2013】森林 启发式合并
- 【算法】树上启发式合并算法
- FPGA作业3:通过例化设计18进制计数器
- 调整数组使奇数全部都位于偶数前面。
- 洛谷mNOIP模拟赛d1t1 斐波那契(90分)
- 我人生中第一篇blog
- 近况整理
- SGU 507 Treediff 启发式合并
- Appium移动 自动化测试-环境搭建(1)
- 让Spring架构减化事务配置
- (HDOJ)Children's Queue(java大数大法好)
- 二十、继承
- Redis个人总结及代码实现
- 有关内存空间
- ubuntu的终端里面,随意点击就出现ctrl+C的效果,出现^C
- python基础入门 01