HDU4008 Parent and son(树形DP LCA)
先记录以1为根时每个节点子树儿子节点的最大与次小值,询问x, y时,先判断x在不在y的子树范围内,若不在,结果为y的儿子结点,后继的最小值。
若x在y的子树范围内,若y儿子最小值是x的前驱,从次小值与父亲节点转移,否则从最小值与父亲节点转移。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<utility>
using namespace std;
typedef long long LL;
const int N = 100008, INF = 0x3F3F3F3F;
#define MS(a, num) memset(a, num, sizeof(a))
#define PB(A) push_back(A)
#define FOR(i, n) for(int i = 0; i < n; i++) int dfn[N][2];
int fa[N];
int son[N][2], des[N];
struct Node{
int to,next;
}edge[N * 2]; int head[N],tot, deg[N];
int tim;
void init(){
memset(head, -1, sizeof(head));
memset(deg, 0, sizeof(deg));
tot = 0;
}
void add(int u, int to){
edge[tot].to=to;
edge[tot].next=head[u];
deg[u]++;
head[u]=tot++;
} void dfs(int u, int f){
fa[u] = f;
dfn[u][0] = tim++; son[u][0] = INF;
son[u][1] = INF;
des[u] = INF;
for(int i = head[u]; ~i ; i = edge[i].next){
int v = edge[i].to;
if(v != f){
dfs(v, u);
son[u][1] = min(son[u][1], v);
if(son[u][0] > son[u][1]){
swap(son[u][0], son[u][1]);
}
des[u] = min(des[u], v);
des[u] = min(des[u], des[v]);
}
}
dfn[u][1] = tim++;
} bool isFa(int x, int y){
if(dfn[x][0] <= dfn[y][0] && dfn[x][1] >= dfn[y][0]){
return true;
}
return false;
} int main(){
int t;
cin>>t;
while(t--){
int n, q;
scanf("%d %d", &n, &q);
init();
for(int i = 0; i < n - 1; i++){
int u, v;
scanf("%d %d", &u, &v);
add(u, v);
add(v, u);
}
tim = 0;
dfs(1, INF);//1号节点父亲注意要为NF,便于处理 int des2 = INF;//1号节点子树后继次小值
int minv = INF;//判断1号节点子树后继最小值从哪个儿子节点发出
for(int i = head[1]; ~i; i = edge[i].next){
int v = edge[i].to;
int tp = min(v, des[v]);
if(tp != des[1] && tp < des2){
des2 = tp;
}
if(tp == des[1]){
minv = v;
}
} while(q--){
int x, y;
scanf("%d %d", &x, &y);
if(deg[y] == 1){
printf("no answers!\n");
continue;
}
if(isFa(y, x)){//x在y子树范围内(以1为根时)
int mson, mdes;
if(isFa(son[y][0], x)){
mson = min(son[y][1], fa[y]);
}else{
mson = min(son[y][0], fa[y]);
} if(y != 1){
mdes = 1;
}else{
//y不是节点1,要判断
if(isFa(minv, x)){
mdes = des2;
}else{
mdes = des[y];
}
}
printf("%d %d\n", mson, mdes); }else{
//x不在y子树范围内(以1为根时),直接输出
printf("%d %d\n", son[y][0], des[y]);
}
}
printf("\n");
} return 0;
}
HDU4008 Parent and son(树形DP LCA)的更多相关文章
- poj3417 Network 树形Dp+LCA
题意:给定一棵n个节点的树,然后在给定m条边,去掉m条边中的一条和原树中的一条边,使得树至少分为两部分,问有多少种方案. 神题,一点也想不到做法, 首先要分析出加入一条边之后会形成环,形成环的话,如果 ...
- hdu_5293_Tree chain problem(DFS序+树形DP+LCA)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5293 被这题打蹦了,看着题解写的,很是爆炸,确实想不到,我用的DFS序+LCA+树形DP,当然也可以写 ...
- poj 3417 树形dp+LCA
思路:我以前一直喜欢用根号n分段的LCA.在这题上挂了,第一次发现这样的LCA被卡.果断改用Tarjan离线算法求LCA. 当前节点为u,其子节点为v.那么: 当以v根的子树中含有连接子树以外点的边数 ...
- POJ 3728 The merchant (树形DP+LCA)
题目:https://vjudge.net/contest/323605#problem/E 题意:一棵n个点的树,然后有m个查询,每次查询找(u->v)路径上的两个数,a[i],a[j],(i ...
- Codeforces Round #343 (Div. 2) E. Famil Door and Roads (树形dp,lca)
Famil Door's City map looks like a tree (undirected connected acyclic graph) so other people call it ...
- HDU 4008 Parent and son
树形DP+LCA+思路.这题可真是有点难度......所以准备详细写一下题解. 题意:给一颗无根树,有Q次询问,每次询问指定一个根节点X,然后让你计算Y节点的儿子和子孙中,编号最小的节点是多少. 我们 ...
- P2495 [SDOI2011]消耗战 lca倍增+虚树+树形dp
题目:给出n个点的树 q次询问 问切断 k个点(不和1号点联通)的最小代价是多少 思路:树形dp sum[i]表示切断i的子树中需要切断的点的最小代价是多少 mi[i]表示1--i中的最小边权 ...
- BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP+树剖lca
BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的 ...
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
随机推荐
- php判断浏览器语言
<?php // 分析 HTTP_ACCEPT_LANGUAGE 的属性 // 这里只取第一语言设置 (其他可根据需要增强功能,这里只做简单的方法演示) preg_match('/^([a-z\ ...
- Ubuntu编译源码程序依赖查找方法
ubuntu平时编译源码程序的时候会提示缺少相关的库或是头文件,可以按照以下两种方法进行查找,然后再安装相应的软件包. 1.使用apt-file查找头文件 安装apt-file sudo apt-ge ...
- vmware-question
1.网卡修改序号ip link set eth3 name eth02.解决克隆虚拟机后网卡设备无法识别启动问题的方法******************************/etc/udev/r ...
- Spring AOP基于配置文件的面向方法的切面
Spring AOP基于配置文件的面向方法的切面 Spring AOP根据执行的时间点可以分为around.before和after几种方式. around为方法前后均执行 before为方法前执行 ...
- 【转】CentOS5.6下配置rsync内网同步数据到外网
[转]CentOS5.6下配置rsync内网同步数据到外网 本文转自:http://www.linuxidc.com/Linux/2012-06/64070.htm 一.需求 卫士那边有一个需求,就是 ...
- Light OJ 1140
数位dp,需要记录前导0. 数位dp中需要注意统计0,00,000……这些数字. 数位dp的写法可以分为两类.由于我们通常采用记忆化搜索的方式进行dp,所以我们有一个记忆化数组. 一种是记忆化数组的意 ...
- Java RuntimeException异常处理汇总
Java中所有异常的父类是Throwable类,在Throwable类下有两大子类: 一个是Error类,指系统错误异常,例如:VirtualMachineError 虚拟机错误,ThreadDeat ...
- PHP写时复制, 变量复制和对象复制不同!!!
2016年3月18日 15:09:28 星期五 一直以为PHP对象也是写时复制....... 其实: PHP的变量是写时复制, 对象是引用的 写时复制: $a = $b; 如果$b的内容不改变, $a ...
- VMware ESXi客户端连接控制台时提示"VMRC控制台连接已断开...正在尝试重新连接"的解决方法
通过vSphere Client连接到安装VMware ESXi虚拟环境的主机时,当启动操作系统,选中控制台时控制台上方提示一行"VMRC控制台的连接已断开...正在尝试重新连接" ...
- ExpressQuantumGrid4的cxGrid的一些使用方法和经验
使用cxGrid有一些时间了,在这里总结一下使用cxGrid的一些方法,希望给刚开始接触cxGrid的人一些帮助. 1.简单介绍:cxGrid右下方的cxGrid1Level1是表示Grid表的层,c ...