BZOJ5479: tree
Description
给出一棵树,根节点为1
给出两个集合,集合由树上节点组成
从两个集合分别选出一个元素,求其LCA
问LCA的最大深度是多少
Input
第一行给出数据组数T
对于每组数据
第一行给出N,M,代表树的节点个数及询问次数
接下来N-1行,每行两个正整数u,v,表示u,v之间有边
接下来2M行,每两个表示一个询问
询问的第一行,第一行正整数a代表集合A中元素个数
接下来a个正整数,表示集合中的节点
询问的第二行,第一行正整数b代表集合B中元素个数
接下来b个正整数,表示集合中的节点
T<=5,N,M<=100000
sigma(a)+sigma(b)<=200000
a,b<=N
Output
对于每个询问,一行一个整数表示结果
Sample Input
1
7 3
1 2
1 3
3 4
3 5
4 6
4 7
1 6
1 7
2 6 7
1 7
2 5 4
2 3 2
Sample Output
3
4
2
Solution
考虑怎么样才会让lca的深度最大,两个点的必须尽可能相近。
那么有一个直观的贪心想法,处理出整个树的dfs序(最好树剖,因为这样会优先编号重儿子),将b数组按dfs序排序,每次对于a中的元素,在b中二分与它dfs序最接近的两个点,对lca的深度取max。
多组数据,记得清空数组。
#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define il inline
namespace io {
#define in(a) a=read()
#define out(a) write(a)
#define outn(a) out(a),putchar('\n')
#define I_int int
inline I_int read() {
I_int x = 0 , f = 1 ; char c = getchar() ;
while( c < '0' || c > '9' ) { if( c == '-' ) f = -1 ; c = getchar() ; }
while( c >= '0' && c <= '9' ) { x = x * 10 + c - '0' ; c = getchar() ; }
return x * f ;
}
char F[ 200 ] ;
inline void write( I_int x ) {
if( x == 0 ) { putchar( '0' ) ; return ; }
I_int tmp = x > 0 ? x : -x ;
if( x < 0 ) putchar( '-' ) ;
int cnt = 0 ;
while( tmp > 0 ) {
F[ cnt ++ ] = tmp % 10 + '0' ;
tmp /= 10 ;
}
while( cnt > 0 ) putchar( F[ -- cnt ] ) ;
}
#undef I_int
}
using namespace io ;
using namespace std ;
#define N 200010
int T;
int n, m, head[N], cnt;
struct edge {
int to, nxt;
} e[N<<1];
int fa[N], dep[N], siz[N], top[N], id[N];
int x, y;
struct Node {
int dfn, val;
}a[N], b[N];
void dfs1(int u) {
siz[u] = 1;
for(int i = head[u]; i; i = e[i].nxt) {
if(e[i].to == fa[u]) continue;
fa[e[i].to] = u;
dep[e[i].to] = dep[u] + 1;
dfs1(e[i].to);
siz[u] += siz[e[i].to];
}
}
int tim = 0;
void dfs2(int u, int topf) {
id[u] = ++tim;
top[u] = topf;
int k = 0;
for(int i = head[u]; i; i = e[i].nxt) {
if(e[i].to == fa[u]) continue;
if(siz[e[i].to] > siz[k]) k = e[i].to;
}
if(!k) return;
dfs2(k, topf);
for(int i = head[u]; i; i = e[i].nxt) {
if(e[i].to == fa[u] || e[i].to == k) continue;
dfs2(e[i].to, e[i].to);
}
}
int lca(int x, int y) {
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
return x;
}
void init() {
cnt = 0; tim = 0;
memset(head, 0, sizeof(head));
memset(dep, 0, sizeof(dep));
memset(id, 0, sizeof(id));
memset(top, 0, sizeof(top));
memset(siz, 0, sizeof(siz));
memset(fa, 0, sizeof(fa));
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
}
void ins(int u, int v) {
e[++cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt;
}
int find(int t) {
int l = 1, r = y, ans = y;
while(l <= r) {
int mid = (l + r) >> 1;
if(b[mid].dfn >= t) ans = mid, r = mid - 1;
else l = mid + 1;
}
return ans;
}
bool operator < (Node a, Node b) {
return a.dfn < b.dfn;
}
int main() {
T = read();
while(T--) {
n = read(), m = read();
init();
for(int i = 1; i < n; ++i) {
int u = read(), v = read();
ins(u, v); ins(v, u);
}
dep[1] = 1;
dfs1(1); dfs2(1, 1);
while(m--) {
int ans = 0;
x = read();
for(int i = 1; i <= x; ++i) a[i].val = read(), a[i].dfn = id[a[i].val];
y = read();
for(int i = 1; i <= y; ++i) b[i].val = read(), b[i].dfn = id[b[i].val];
sort(b + 1, b + y + 1);
for(int i = 1; i <= x; ++i) {
int t = find(a[i].dfn);
ans = max(ans, dep[lca(b[t].val, a[i].val)]);
ans = max(ans, dep[lca(b[t - 1].val, a[i].val)]);
}
outn(ans);
}
}
}
BZOJ5479: tree的更多相关文章
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- SAP CRM 树视图(TREE VIEW)
树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...
- 无限分级和tree结构数据增删改【提供Demo下载】
无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...
- 2000条你应知的WPF小姿势 基础篇<45-50 Visual Tree&Logic Tree 附带两个小工具>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...
- Leetcode 笔记 110 - Balanced Binary Tree
题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...
- Leetcode 笔记 100 - Same Tree
题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...
- Leetcode 笔记 99 - Recover Binary Search Tree
题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...
- Leetcode 笔记 98 - Validate Binary Search Tree
题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...
- Leetcode 笔记 101 - Symmetric Tree
题目链接:Symmetric Tree | LeetCode OJ Given a binary tree, check whether it is a mirror of itself (ie, s ...
随机推荐
- EXTENDED LIGHTS OUT (高斯消元)
In an extended version of the game Lights Out, is a puzzle with 5 rows of 6 buttons each (the actual ...
- RootConfig类
package com.ssm.yjblogs.config; import java.util.Properties; import javax.sql.DataSource; import org ...
- 20155228 实验二 Java面向对象程序设计
20155228 实验二 Java面向对象程序设计 实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原 ...
- samba共享目录无法访问的一般解决方案,非用户登录和读写权限问题
配smb,被第四点坑了很久,特此转载. 由于这5点都是比较普通的情况,不涉及用户登录和读写权限问题 1)关闭防火墙: #sevice iptables stop 2)修改 /etc/samba/smb ...
- foreach 语句
foreach 语句很适合用来枚举 如数组.列表.集合之类的数据结构中的元素. 不必准确知道元素个数.如果基数据不包含任何元素,则foreach循环不执行 foreach(<元素> ...
- python GIL 全局锁,多核cpu下的多线程性能究竟如何?
python GIL 全局锁,多核cpu下的多线程性能究竟如何?GIL全称Global Interpreter Lock GIL是什么? 首先需要明确的一点是GIL并不是Python的特性,它是在实现 ...
- TensorFlow入门,基本介绍,基本概念,计算图,pip安装,helloworld示例,实现简单的神经网络
TensorFlow入门,基本介绍,基本概念,计算图,pip安装,helloworld示例,实现简单的神经网络
- Selenium+Java自动化测试的方法
1.设置等待时间Thread.sleep(2000); (1000代表1s)2.断言assertion:验证应用程序的状态是否同所期望的一致.常见的断言包括:验证页面内容,如标题是否为X或当前位置是否 ...
- Java学习技术分享:Java中的原子操作
学习java需要有一套完整的学习线路,需要有条理性,当下学习java已经有一段时间了,由当初的懵逼状态逐渐好转,也逐渐养成了写技术学习笔记的习惯,今天总结了一下java中的原子操作. 1.Java中的 ...
- 结合sklearn的可视化工具Yellowbrick:超参与行为的可视化带来更优秀的实现
https://blog.csdn.net/qq_34739497/article/details/80508262 Yellowbrick 是一套名为「Visualizers」的视觉诊断工具,它扩展 ...