给定一棵树,求出当x为根时y的最小儿子和最小后代各是多少。

  一道中等的树形DP,首先以1为根进行DP可以求出每个节点的最小儿子和最小后代。只有当x为y的孩子时才需要讨论,否则直接输出前面DP的结果即可,这里画个图就可以看出来,下面只讨论x为y的孩子的情况。

  如果y的最小儿子是x的祖宗节点,那这时该最小儿子已经变成了y的父亲,在选取最小儿子时不能在考虑这个点,应该换选次小儿子,所以每个点的次小儿子也要在DP时预处理出来,另外,这时y的原父亲在新树中已经变成了y的儿子,所以在选取最小儿子时要考虑父节点。至于最小后代,如果y不是根节点,那么最小后代必然是根节点1了,如果y节点是根节点,就先找到最小后代在它那个儿子的子树中,如果最小后代和x在同一棵子树中,那么现在已经成为了跟节点的父亲,换而选取其它子树中的最小后代,否则就直接选取最小根节点。

  至于祖宗节点的判断,用进出时间戳就可以了,儿子节点的时间戳必然是被父节点夹在中间的。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define INF 0x3fffffff
#define MAXN 100005struct edge{int v,n;
}e[MAXN<<1];
int first[MAXN],es;
int mins[MAXN][2],mind[MAXN],mind2,mindv,dfn[MAXN][2],fat[MAXN],ds;
void addedge(int u,int v){e[es].v=v,e[es].n=first[u],first[u]=es++;
}
inline int min(int x,int y){return x<y?x:y;}
inline void swap(int &x,int &y){x^=y,y=x^y,x=x^y;}
void dp(int u,int f){dfn[u][0]=++ds;for(int i=first[u];i!=-1;i=e[i].n){int v=e[i].v;if(v==f)continue;fat[v]=u;dp(v,u);//跟新最小和次小儿子if(v<mins[u][1])mins[u][1]=v;if(mins[u][1]<mins[u][0])swap(mins[u][0],mins[u][1]);//跟新最小后代int tmp=min(v,mind[v]);if(tmp<mind[u])mind[u]=tmp;}dfn[u][1]=++ds;
}
//判读u是不是v的father
int isfather(int u,int v){return dfn[u][0]<=dfn[v][0]&&dfn[v][1]<=dfn[u][1];
}
int cas,n,q,tu,tv;
int main(){//freopen("test.in","r",stdin);scanf("%d",&cas);while(cas--){scanf("%d%d",&n,&q);for(int i=1;i<=n;i++)first[i]=-1;es=0;for(int i=0;i<n-1;i++){scanf("%d%d",&tu,&tv);addedge(tu,tv);addedge(tv,tu);}for(int i=1;i<=n;i++)mins[i][0]=mins[i][1]=INF;for(int i=1;i<=n;i++)mind[i]=INF;ds=0,fat[1]=INF;dp(1,-1);//跟新根节点次大的孩子,同时记录最小后代与1的最近节点mind2=INF;for(int i=first[1];i!=-1;i=e[i].n){int v=e[i].v,tmp=min(v,mind[v]);if(tmp!=mind[1]&&tmp<mind2)mind2=tmp;if(tmp==mind[1])mindv=v;}while(q--){scanf("%d%d",&tu,&tv);//如果这个点只连了一条边,说明无孩子if(e[first[tv]].n==-1){printf("no answers!\n");//如果tv是tu的父亲(以1为根)}else if(isfather(tv,tu)){int mis,mid;//如果最小的儿子是tu的祖宗节点,则此时已经成为了tv的父亲节点,换为次小的儿子//同时原来的父亲节点已经变成了孩子,要一起考虑if(isfather(mins[tv][0],tu))mis=min(mins[tv][1],fat[tv]);else mis=min(mins[tv][0],fat[tv]);//如果tv是根节点要特判,选取他最大或者次大的后代,否则最小后代就是1if(tv==1)mid=isfather(mindv,tu)?mind2:mind[1];else mid=1;printf("%d %d\n",mis,mid);//其它情况}else{printf("%d %d\n",mins[tv][0],mind[tv]);}}printf("\n");}return 0;
}

转载于:https://www.cnblogs.com/swm8023/archive/2012/08/27/2659248.html

HDU4008 Parent and son [树形DP]相关推荐

  1. UOJ #131 BZOJ 4199 luogu P2178【NOI2015】品酒大会 (后缀自动机、树形DP)

    UOJ #131 BZOJ 4199 luogu P2178[NOI2015]品酒大会 (后缀自动机.树形DP) 水是水,但是写出了不少问题,因此写一发博客. https://www.luogu.or ...

  2. [树形dp] Jzoj P5233 概率博弈

    Description 小A和小B在玩游戏.这个游戏是这样的: 有一棵n个点的以1为根的有根树,叶子有权值.假设有m个叶子,那么树上每个叶子的权值序列就是一个1->m 的排列. 一开始在1号点有 ...

  3. POJ 3342 树形DP+Hash

    这是很久很久以前做的一道题,可惜当时WA了一页以后放弃了. 今天我又重新捡了起来.(哈哈1A了) 题意: 没有上司的舞会+判重 思路: hash一下+树形DP 题目中给的人名hash到数字,再进行运算 ...

  4. 0x54. 动态规划 - 树形DP(习题详解 × 12)

    目录 0x54.1 树形DP Problem A. 没有上司的舞会 Problem B. 战略游戏 0x54.2 树上背包 Problem A. 选课 Problem B.[数据加强版]选课(树上背包 ...

  5. 【树形DP】树的重心详解+多组例题详解

    目录 定义: 性质: 算法分析: POJ 1655 Balancing Act(求重心) POJ 3107 Godfather P1364 医院设置(树形DP) 定义: 树的重心也叫树的质心.对于一棵 ...

  6. 树形dp——树的重心(2) 代码调试理解

    和树的最大独立问题类似,先任选一个结点作为根节点,把无根树变成有根树,然后设d(i)表示以i为根的子树的结点的个数.不难发现d(i)=∑d(j)+1,j∈s(i).s(i)为i结点的所有儿子结点的编号 ...

  7. [WC2018]通道——边分治+虚树+树形DP

    题目链接: [WC2018]通道 题目大意:给出三棵n个节点结构不同的树,边有边权,要求找出一个点对(a,b)使三棵树上这两点的路径权值和最大,一条路径权值为路径上所有边的边权和. 我们按照部分分逐个 ...

  8. layui树形父子不关联_DP专题7 | 没有上司的舞会 洛谷1352(树形DP)

    高能预警:这是一篇超过5分钟的学习文章,暑假了可以多学会 本篇继续咱们的DP专题,树形DP入门.动态规划每一个类型的DP都是深坑,期望童鞋们自己在这个系列的基础上多花时间进行拓展,学习愉快~ 在讨论树 ...

  9. 【BZOJ-1864】三色二叉树 树形DP

    1864: [Zjoi2006]三色二叉树 Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 659  Solved: 469 [Submit][Statu ...

最新文章

  1. 赠书 | 算力时代,用 Python 来快速解决复杂问题
  2. python读取指定行的txt_【Python】读取txt文件,获取指定行中指定位置数据
  3. 【UGV】小车一些图片 麦轮版小车
  4. python并发编程调优_Python并发编程-并发解决方案概述
  5. 将Windows 8.1 系统窗口背景设置成淡绿色?
  6. 服务提供者和服务消费者
  7. 【NOIP2010】【P1317】乌龟棋
  8. Java代理模式——静态代理动态代理
  9. python连接mysql的一些基础知识+安装Navicat可视化数据库+flask_sqlalchemy写数据库
  10. 干货:结合Scikit-learn介绍几种常用的特征选择方法
  11. ref:PHP反序列化漏洞成因及漏洞挖掘技巧与案例
  12. 分布式光伏融资难点分析
  13. JavaWeb学习总结(一)JavaWeb入门与Tomcat
  14. HTML5 postMessage解决跨域|跨窗口通信
  15. 【6.10校内test】T3 加分二叉树
  16. 找出数组中第二大的值
  17. 使用jekins自动构建部署java maven项目(jdk1.7+tomcat7.0+jenkins2.19.3)
  18. 2020年居家实习日志
  19. java commons math_Apache Commons Math
  20. jpg怎么合成一份_如何将多张图片合成一个文件

热门文章

  1. 关于new String(new byte[]{0})
  2. APACHE利用Limit模块限制IP连接数
  3. grails 转为java_创建一个grails项目,然后转成maven项目
  4. python使用复合语句def创建函数对象_【收藏】Python实用技巧-成为Pythoner必经之路...
  5. 5GS 协议栈 — N1 接口的协议栈(NAS)
  6. PyQt4 Python GUI窗体应用程序
  7. CentOS6.5 升级 Python 2.7 版本
  8. 如何实现分享链接到微信朋友圈时显示自定义LOGO以及名称介绍
  9. 收藏:《Exchange 2013 OWA/ECP 登陆后白屏》
  10. openstack中glance组件images的全部python API 汇总