/*
先来个倍增
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 10010
using namespace std;
int T,n,num,head[maxn],st,end,anc,fa[maxn][],dep[maxn],out[maxn],root;
struct node
{
int u,v,t,pre;
}e[maxn*];
void Add(int from,int to)
{
num++;
e[num].u=from;
e[num].v=to;
e[num].pre=head[from];
head[from]=num;
}
void Dfs(int now,int from,int c)
{
fa[now][]=from;
dep[now]=c;
for(int i=head[now];i;i=e[i].pre)
if(e[i].v!=from)
Dfs(e[i].v,now,c+);
}
void Get_fa()
{
for(int j=;j<=;j++)
for(int i=;i<=n;i++)
fa[i][j]=fa[fa[i][j-]][j-];
}
int Get_same(int a,int t)
{
for(int i=;i<=t;i++)
a=fa[a][];
return a;
}
int LCA(int a,int b)
{
if(dep[a]<dep[b])swap(a,b);
a=Get_same(a,dep[a]-dep[b]);
if(a==b)return a;
for(int i=;i>=;i--)
if(fa[a][i]!=fa[b][i])
{
a=fa[a][i];b=fa[b][i];
}
return fa[a][];
}
int main()
{
scanf("%d",&T);
while(T--)
{
memset(head,,sizeof(head));
memset(fa,,sizeof(fa));
memset(out,,sizeof(out));
memset(dep,,sizeof(dep));
num=;root=;
scanf("%d",&n);
int x,y;
for(int i=;i<=n-;i++)
{
scanf("%d%d",&x,&y);
Add(x,y);Add(y,x);
out[y]=;
}
for(int i=;i<=n;i++)
if(out[i]==)root=i;
Dfs(root,root,);
Get_fa();
scanf("%d%d",&st,&end);
anc=LCA(st,end);
printf("%d\n",anc);
}
return ;
}
/*
离线Tarjan
我们Dfs整张图的时候 对于一组u v
我们一定按照 u s v 的顺序跑完
此时u v 在以s为根的子树里
那么我们借助并茶几 将u v的fa 的anc赋值为s
这样我们查询u v 的时候就能找到s
如果我们求 st end 的lca
当我们遍历到st 或者end的时候 只需要判断另一个是不是已经被访问过
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define maxn 100010
using namespace std;
int T,n,m,fa[maxn],st,end,anc[maxn];
vector<int>a[maxn];
int root[maxn],f[maxn];
void init()
{
scanf("%d",&n);
int x,y;
for(int i=;i<=n;i++)
{
fa[i]=i;root[i]=;
}
for(int i=;i<=n-;i++)
{
scanf("%d%d",&x,&y);
a[x].push_back(y);
fa[y]=x;root[y]=;
}
}
int find(int x)
{
if(x!=fa[x])fa[x]=find(fa[x]);
return fa[x];
}
void Union(int x,int y)
{
int r1=find(x);
int r2=find(y);
if(r1!=r2)fa[r2]=r1;
}
void LCA(int parent)
{
anc[parent]=parent;//初始化自己的lca为自己
for(int i=;i<a[parent].size();i++)
{
LCA(a[parent][i]);
Union(parent,a[parent][i]);
anc[find(parent)]=parent;//把自己和自己子孙们的lca赋值为它
}
f[parent]=;
if(st==parent&&f[end]==)
{
printf("%d\n",anc[find(end)]);
return;
}
if(end==parent&&f[st]==)
{
printf("%d\n",anc[find(st)]);
return;
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
memset(f,,sizeof(f));
memset(a,,sizeof(a));
init();
scanf("%d%d",&st,&end);
for(int i=;i<=n;i++)
if(root[i])
LCA(i);
}
return ;
}

poj 1330 LCA (倍增+离线Tarjan)的更多相关文章

  1. POJ 1330 LCA裸题~

    POJ 1330 Description A rooted tree is a well-known data structure in computer science and engineerin ...

  2. POJ 1330 LCA最近公共祖先 离线tarjan算法

    题意要求一棵树上,两个点的最近公共祖先 即LCA 现学了一下LCA-Tarjan算法,还挺好理解的,这是个离线的算法,先把询问存贮起来,在一遍dfs过程中,找到了对应的询问点,即可输出 原理用了并查集 ...

  3. POJ 1330 Nearest Common Ancestors(Tarjan离线LCA)

    Description A rooted tree is a well-known data structure in computer science and engineering. An exa ...

  4. poj 1986 Distance Queries(LCA:倍增/离线)

    计算树上的路径长度.input要去查poj 1984. 任意建一棵树,利用树形结构,将问题转化为u,v,lca(u,v)三个点到根的距离.输出d[u]+d[v]-2*d[lca(u,v)]. 倍增求解 ...

  5. POJ 1470 Closest Common Ancestors (LCA,离线Tarjan算法)

    Closest Common Ancestors Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 13372   Accept ...

  6. LCA/在线(倍增)离线(Tarjan)

    概念 祖先 公共祖先 最近公共祖先 方法1:暴力爬山法 方法2:倍增 求公共祖先 求俩点的距离 Tarjan 概念 祖先 有根树中,一个节点到根的路径上的所有节点被视为这个点的祖先,包括根和它本身 公 ...

  7. poj 1330 LCA最近公共祖先

    今天学LCA,先照一个模板学习代码,给一个离线算法,主要方法是并查集加上递归思想. 再搞,第一个离线算法是比较常用了,基本离线都用这种方法了,复杂度O(n+q).通过递归思想和并查集来寻找最近公共祖先 ...

  8. LCA:倍增与tarjan

    学了好久(一两个星期)都没彻底搞懂的lca,今天总算理解了.就来和大家分享下我自己的心得 首先,如果你还不懂什么是lca,出门左转自行百度 首先讲倍增 倍增的思想很简单,首先进行预处理,用一个深搜将每 ...

  9. poj 1330 LCA

    #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #i ...

随机推荐

  1. G - A+B for Input-Output Practice (VI)

      Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   Description You ...

  2. 省队集训Day3 light

    [问题描述] “若是万一琪露诺(俗称 rhl)进行攻击,什么都好,冷静地回答她的问题来吸引她.对方表现出兴趣的话,那就慢慢地反问.在她考虑答案的时候,趁机逃吧.就算是很简单的问题,她一定也答不上来.” ...

  3. 批处理文件的@echo off是什么意思?

    @echo off 关闭回显 @echo on 打开回显 @echo off并不是DOS程序中的, 而是DOS批处理中的. 当年的DOS,所有操作都用键盘命令来完成, 当你每次都要输入相同的命令时, ...

  4. Plan-9效应:为什么东西不坏就不要去修它

    http://www.aqee.net/the-plan-9-effect-or-why-you-should-not-fix-it-if-it-aint-broken/ Plan-9是一个很棒的.很 ...

  5. pecl安装php的ev扩展时的报错处理

    pecl安装php的ev扩展,安装完毕后php.ini中加入扩展extension=ev.so,然后重启php-fpm出现以下报错 PHP Warning:  PHP Startup: Unable ...

  6. Zabbix的LLD功能--Low-level discovery

    感觉这个主题是和一个主题是一个系列,而且更基础. 准备深入研究一下... 相关文档准备: https://www.zabbix.com/documentation/2.0/manual/discove ...

  7. Visual C++ 8.0对象布局的奥秘:虚函数、多继承、虚拟继承(VC直接输出内存布局)

    原文:VC8_Object_Layout_Secret.html 哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleCl ...

  8. 使用spring-amqp结合使用rabbitmq

    maven 依赖包配置如下: <dependencies> <dependency> <groupId>org.springframework.amqp</g ...

  9. java学习之break 和 continue

    java当中比较特殊的两个关键字:break,continue.从字面意思来看的话break就是打断的意思,而continue就是继续的意思. 这两个关键词用途范围是很明确的: break:只能用在s ...

  10. Unity 动态载入Panel并实现淡入淡出

    unity版本:4.5 NGUI版本:3.6.5 参考链接:http://tieba.baidu.com/p/3206366700,作者:百度贴吧 水岸上 动态载入NGUI控件,这里用Panel为例说 ...