HDU-6031 Innumerable Ancestors(二分+树上倍增)
题意
给一棵树,$m$次询问,每次询问给两个点集问从两个点集中各取一个点的$LCA$的最大深度。
思路
二分答案。对于某个二分过程中得到的$Mid$,如果可行则两个点集在$Mid$所在的深度存在公共的祖先。枚举点集内的点,倍增找到他在这个深度的祖先就行。
代码
#include <bits/stdc++.h>
#define DBG(x) cerr << #x << " = " << x << endl using namespace std; const int N = 100000 + 5;
const int M = 200000 + 5; int n, m, k1, k2;
int tot, head[N];
int A[N], B[N];
int d[N], f[N][25], maxd, t;
struct edgenode {
int to, next;
}edge[M];
set<int> st;
queue<int> Q; void addedge(int u, int v) {
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
} void bfs() {
while(!Q.empty()) Q.pop();
Q.push(1); d[1] = 1;
while(!Q.empty()) {
int tmp = Q.front(); Q.pop();
for(int i = head[tmp]; i != -1; i = edge[i].next) {
int v = edge[i].to;
if(d[v] != 0) continue;
d[v] = d[tmp] + 1;
f[v][0] = tmp;
for(int j = 1; j <= t; j++) f[v][j] = f[f[v][j - 1]][j - 1];
Q.push(v);
}
}
} int Find(int x, int dep) {
if(d[x] < dep) return -1;
if(d[x] == dep) return x;
for(int i = t; i >= 0; i--) if(d[f[x][i]] >= dep) x = f[x][i];
return x;
} bool judge(int x) {
st.clear();
for(int i = 1; i <= k1; i++) {
int fa = Find(A[i], x);
if(fa != -1) st.insert(fa);
}
for(int i = 1; i <= k2; i++) {
int fa = Find(B[i], x);
if(st.find(fa) != st.end()) return true;
}
return false;
} int calc(int L, int R) {
int res = L;
while(L <= R) {
int Mid = (L + R) / 2;
if(judge(Mid)) res = max(res, Mid), L = Mid + 1;
else R = Mid - 1;
}
return res;
} int main() {
while(scanf("%d%d", &n, &m) != EOF){
tot = 0;
memset(head, -1, sizeof head);
memset(f, 0, sizeof f);
memset(d, 0, sizeof d);
for(int i = 1, x, y; i <= n - 1; i++) {
scanf("%d%d", &x, &y);
addedge(x, y);
addedge(y, x);
}
t = (int)(log(n) / log(2)) + 1;
bfs();
while(m--) {
maxd = 1;
scanf("%d", &k1);
for(int i = 1; i <= k1; i++) scanf("%d", &A[i]), maxd = max(maxd, d[A[i]]);
scanf("%d", &k2);
for(int i = 1; i <= k2; i++) scanf("%d", &B[i]);
printf("%d\n", calc(1, maxd));
}
}
return 0;
}
忘了多组读入痛失1A...
HDU-6031 Innumerable Ancestors(二分+树上倍增)的更多相关文章
- HDU 6031 Innumerable Ancestors
树状数组,倍增,枚举,$dfs$序. 对于每一次的询问,可以枚举$B$集合中的所有点,对于每一个点,在树上二分$LCA$,找到最低的更新答案. 判断是否是$LCA$可以搞个$dfs$序,将$A$集合中 ...
- HDU 4822 Tri-war(LCA树上倍增)(2013 Asia Regional Changchun)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4822 Problem Description Three countries, Red, Yellow ...
- HDU6031 Innumerable Ancestors 倍增 - 题意详细概括 - 算法详解
去博客园看该题解 题目 查看原题 - HDU6031 Innumerable Ancestors 题目描述 有一棵有n个节点的有根树,根节点为1,其深度为1,现在有m个询问,每次询问给出两个集合A和B ...
- [树上倍增+二分答案][NOIP2012]运输计划
题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 公元 2044 年,人类进入了宇宙纪元 L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间,这 n-1n− ...
- 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组
题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...
- 最近公共祖先 LCA (Lowest Common Ancestors)-树上倍增
树上倍增是求解关于LCA问题的两个在线算法中的一个,在线算法即不需要开始全部读入查询,你给他什么查询,他都能返回它们的LCA. 树上倍增用到一个关键的数组F[i][j],这个表示第i个结点的向上2^j ...
- 树上倍增求LCA及例题
先瞎扯几句 树上倍增的经典应用是求两个节点的LCA 当然它的作用不仅限于求LCA,还可以维护节点的很多信息 求LCA的方法除了倍增之外,还有树链剖分.离线tarjan ,这两种日后再讲(众人:其实是你 ...
- LCA__st算法&&树上倍增
st表 #include<cstdio> #include<algorithm> #include<cmath> using namespace std; ]; ] ...
- [HNOI2016]树(可持久化线段树+树上倍增)
[HNOI2016]树(可持久化线段树+树上倍增) 题面 给出一棵n个点的模板树和大树,根为1,初始的时候大树和模板树相同.接下来操作m次,每次从模板树里取出一棵子树,把它作为新树里节点y的儿子.操作 ...
随机推荐
- 《Python 数据科学实践指南》读书笔记
文章提纲 全书总评 C01.Python 介绍 Python 版本 Python 解释器 Python 之禅 C02.Python 基础知识 基础知识 流程控制: 函数及异常 函数: 异常 字符串 获 ...
- SQLAchemy模块
老师的博客:http://www.cnblogs.com/wupeiqi/articles/5713330.html 有一篇习详细的博客: http://www.keakon.net/2012/12/ ...
- angularjs(显示和隐身) 依赖注入
1.angularjs 隐身参数注入control: 1.control名称 , 2.function,在function内部直接传递参数和方法. var myapp=angular.model(&q ...
- CF396C On Changing Tree
CF396C On Changing Tree 给定一棵以 \(1\) 为根的树,初始时所有点权为 \(0\) 有 \(m\) 次操作,分为两种 \(1\ u\ x\ k\) 表示给以 \(u\) 的 ...
- Apache Jakarta Commons 工具集简介
Apache Jakarta Commons 工具集简介[转] Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动.我选了一些比较常用的项目做简单介绍.文 ...
- git@github.com: Permission denied (publickey).////remote: Permission to xxx/test.git denied to xxx.等权限问题
Error msg git@github.com: Permission denied (publickey) 或者: remote: Permission to xxx/test.git denie ...
- Scrum Meeting 博客
笨拙软件工程 Scrum Meeting 博客汇总 一.Alpha阶段 [alpha阶段]第一次Scrum Meeting [alpha阶段]第二次Scrum Meeting [alpha阶段]第三次 ...
- day07(数据类型的相互转换 ,字符编码)
一,复习: ''' 1,深浅拷贝 ls = [1,'a',[10]] 值拷贝:直接赋值 ls1 = ls,ls中的任何值发生改变,ls1也随之发生改变 浅拷贝:通过copy()方法 ls2 = ls. ...
- php将字符串转为二进制数据串
/** * 将字符串转换成二进制 * @param type $str * @return type */ function StrToBin($str){ //1.列出每个字符 $arr = pre ...
- Smart Indenter for VBE(64bits smart indent addin for VBA Editor),VBA开发必备的智能排版工具。
原始出处:www.cnblogs.com/Charltsing/p/SmartIndenter64.html 作者QQ: 564955427 最近更换电脑,改用64位office做开发.VBA代码美化 ...