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的儿子.操作 ...
随机推荐
- Linux(CentOS7)下如何配置多个Tomcat容器
一.Linux版本 二.上传并解压apache-tomcat-7.0.90压缩包,然后复制粘贴出来多个tomcat 解压缩 tar -xzvf apache-tomcat-7.0.90.tar.gz ...
- Proverbs(谚语)
Proverbs(谚语) 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 更多请查看:English 1. Every man is the maste ...
- 利用Sonar定制自定义扫描规则
上有3种方法可以自定义soanr的代码校验规则: 直接在sonar的web接口中增加XPath规则: 通过插件的功能来增加自定义规则,比如checkstyle,pmd等插件是允许自定义规则的: 通 ...
- 014_zk路径过滤分析
一.线上zk访问延迟特别高需要统计一段时间内的zk写入路径top10,实现如下: #!/usr/bin/env python # -*- coding:utf-8 -*- import re,trac ...
- mysql 新建用户并赋予远程访问权限
不多说直接上代码 [root@demo /]# mysql -u root -p #登录服务器数据库 Enter password:123xxx #1.创建一个新用户 testuser 密码为 tes ...
- 使用.Net Core Mvc +SqlSugar +Autofac+AutoMapper+....
开源地址:https://github.com/AjuPrince/Aju.Carefree 目前用到了 SqlSugar.Dapper.Autofac.AutoMapper.Swagger.Redi ...
- C#创建安装、卸载部署程序
分享3: 需求:对已经开发的应用程序进行安装封装操作,即创建安装.卸载部署程序: 分析:程序的开发是为了在不同的人在不同的机器上使用,为了使不同机器使用该软件就需要见程序安装包,并且保证安装包中必须包 ...
- js 对象 类型转换
对象不相等 var o = {x: 1}, p = {x: 1}; console.log(o == p); console.log(o === p); var arr1 = [], arr2 = [ ...
- Glide和Picasso的区别
首先简单的介绍下两个库的出身: Picasso是Square公司出品的一款非常优秀的开源图片加载库Glide是由Google开发,基于 Picasso,依然有保存了Picasso的简洁风格,但是在此做 ...
- [USACO19FEB]Mowing Mischief
题目大意: 给定平面上的一些点,求这些点的一个\(LIS\),并且还需要满足下列式子最小: \[ \sum_{i=1}^{n-1}(a[i+1].x-a[i].x)*(a[i+1].y-a[i].y) ...