【HDU 6031]】 Innumerable Ancestors
题意
有一棵有n个结点的树,这里有m个询问,每个询问给出两个非空的结点集合A和B,有些结点可能同时在这两个集合当中。你需要从A和B中分别选择一个节点x和y(可以是同一个结点)你的目标是使LCA(x,y)的深度最大。n,m<=100000
分析
LCA算法每次查询的复杂度都是logn的,如果每个查询都枚举两个集合,那么均摊的时间复杂度是n^2logn(好像··大概··是吧??
听说这个题可以通过给两个集合排序爆过去????为啥我失败了?姿势不对吗?
这个题的标准解法是二分+LCA(倍增预处理)
对于每次查询,我们二分最大深度。然后怎么写check呢?把集合A里面的,深度为这个二分出来的值的这个点,加入一个set。然后枚举集合B,如果B里面这个深度的祖先在这个set里面,那么就返回正确。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <set> using namespace std;
const int maxn=+;
vector<int>G[maxn];
int n,m,k1,k2;
int f[maxn][],d[maxn],A[maxn],B[maxn];
void bfs(){
queue<int>q;
memset(d,,sizeof(d));
memset(f,,sizeof(f));
q.push();d[]=;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=;i<G[u].size();i++){
int v=G[u][i];
if(d[v])continue;
d[v]=d[u]+;
f[v][]=u;
for(int j=;j<=;j++){
f[v][j]=f[f[v][j-]][j-];
}
q.push(v);
}
}
return ;
}
int lca(int x,int y){
if(d[x]>d[y])swap(x,y);
for(int i=;i>=;i--)
if(d[f[y][i]]>=d[x])y=f[y][i];
if(x==y)return x;
for(int i=;i>=;i--)
if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
return f[x][];
}
int query(int u,int fa){
if(fa==)return u;
for(int i=;i>=;i--){
if(fa>=(<<i)){
u=f[u][i];
fa-=(<<i);
}
}
return u;
}
bool check(int deep){
set<int>S;
for(int i=;i<=k1;i++){
if(deep>d[A[i]])continue;
int res=query(A[i],d[A[i]]-deep);
S.insert(res);
}
for(int i=;i<=k2;i++){
if(deep>d[B[i]])continue;
int res=query(B[i],d[B[i]]-deep);
if(S.count(res))return true;
}
return false;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=;i<=n;i++)G[i].clear();
for(int i=;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
G[a].push_back(b);
G[b].push_back(a);
}
bfs();
for(int i=;i<=m;i++){
int L,R,mid;
scanf("%d",&k1);
R=;
for(int j=;j<=k1;j++){
scanf("%d",&A[j]);
R=max(R,d[A[j]]);
}
scanf("%d",&k2);
for(int j=;j<=k2;j++)
scanf("%d",&B[j]);
L=;
while(L+<R){
mid=L+(R-L)/;
if(check(mid)){
L=mid;
}else{
R=mid-;
}
}
if(check(R))
printf("%d\n",R);
else
printf("%d\n",L);
}
}
return ;
}
【HDU 6031]】 Innumerable Ancestors的更多相关文章
- 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题
[HDU 3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...
- 【HDU 5647】DZY Loves Connecting(树DP)
pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...
- -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】
[把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...
- 【HDU 2196】 Computer(树的直径)
[HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...
- 【HDU 2196】 Computer (树形DP)
[HDU 2196] Computer 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 刘汝佳<算法竞赛入门经典>P282页留下了这个问题 ...
- 【HDU 5145】 NPY and girls(组合+莫队)
pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...
- 【hdu 1043】Eight
[题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=1043 [题意] 会给你很多组数据; 让你输出这组数据到目标状态的具体步骤; [题解] 从12345 ...
- 【HDU 3068】 最长回文
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3068 [算法] Manacher算法求最长回文子串 [代码] #include<bits/s ...
- 【HDU 4699】 Editor
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4699 [算法] 维护两个栈,一个栈放光标之前的数,另外一个放光标之后的数 在维护栈的同时求最大前缀 ...
随机推荐
- Android 进阶13:几种进程通信方式的对比总结
不花时间打基础,你将会花更多时间解决那些不必要的问题. 读完本文你将了解: RPC 是什么 IDL 是什么 IPC 是什么 Android 几种进程通信方式 如何选择这几种通信方式 Thanks RP ...
- C语言中的extern关键字用法
在C语言中,修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”. 1. extern修饰变量的声明.举例来说,如果文件a.c需要引用b.c中变量int v ...
- POJ 2954 Triangle (pick 定理)
题目大意:给出三个点的坐标,问在这三个点坐标里面的整数坐标点有多少个(不包含边上的) 匹克定理:I = (A-E) / 2 + 1; A: 表示多边形面积 I : 表示多边形内部的点的个数 E: 表示 ...
- LeetCode Replace Words
原题链接在这里:https://leetcode.com/problems/replace-words/description/ 题目: In English, we have a concept c ...
- matlab中的开方sqrt用牛顿迭代法实现的代码
function kaifang = KAIFANG(a)g0=a/2;g1=(g0+a./g0)/2;for i=0 : 299g0=g1;g1=(g0+a./g0)/2;endkaifang = ...
- model里面字段choices的values值的选择
代码如下: Model: class Person(models.Model): name = models.CharField(max_length=200) CATEGORY_CHOICES = ...
- 对Tornado异步操作Sqlalchemy方法的选定 不错
使用原因 在一个实时通讯的项目中,由于需要使用Websocket这一协议,便在Python框架中选定了Tornado,也同时使用了Sqlalchemy这一ORM框架. 大家都知道Tornado有异步非 ...
- 时间js
function DateUtil(){ this.url = ""; this.op={ partten:{mdy:"m/d/y",ymd:"y/m ...
- Linux环境抓包命令
有时候有些接口调用问题不好定位或者日志不够详细,那么我们往往会选择通过抓包来看详细的通讯过程.抓包有相关软件,这里说如何直接在环境里抓.假如现在我们在 Linux 下部署了 Tomcat 服务器,端口 ...
- java代码求分数等级的输出~~~
总结:无论是switch-case-break语句 都不要忘了跳出当前循环,即break; 还有这个输入的分数我如何控制在100以内???? package com.c2; //实现分数等级的输出. ...