给定一棵树求任意两个节点的公共祖先

tarjan离线求LCA思想是,先把所有的查询保存起来,然后dfs一遍树的时候在判断。如果当前节点是要求的两个节点当中的一个,那么再判断另外一个是否已经访问过,如果访问过的话,那么它的最近公共祖先就是当前节点祖先。

下面是tarjan离线模板:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = ; struct Edge {
int to, next;
}edge[maxn * ];
//查询
struct Query {
int q, next;
int index;
}query[maxn * ]; int tot, head[maxn];
//查询的前向星
int cnt, h[maxn];
//查询的答案保存在ans中
int ans[maxn * ];
int fa[maxn];//并查集
int r[maxn];//并查集集合个数
int ancestor[maxn];//祖先
bool vis[maxn];//访问标记
int Q;//查询总数
void init(int n)
{
tot = ;
cnt = ;
Q = ;
memset(h, -, sizeof(h));
memset(head, -, sizeof(head));
memset(fa, -, sizeof(fa));
memset(ancestor, , sizeof(ancestor));
memset(vis, false, sizeof(vis));
for (int i = ; i <= n; i++) r[i] = ;
}
void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
void addquery(int u, int v, int index)
{
query[cnt].q = v;
query[cnt].index = index;
query[cnt].next = h[u];
h[u] = cnt++;
}
int find(int x)
{
if (fa[x] == -) return x;
return fa[x] = find(fa[x]);
}
void Union(int x, int y)
{
int t1 = find(x);
int t2 = find(y);
if (t1 != t2)
{
if (t1 < t2)
{
fa[t1] = t2;
r[t2] += r[t1];
}
else
{
fa[t2] = t1;
r[t1] += r[t2];
}
}
}
void LCA(int u)//tarjan离线算法
{
vis[u] = true;
ancestor[u] = u;
for (int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if (vis[v]) continue;
LCA(v);
Union(u, v);
ancestor[find(u)] = u;
}
for (int i = h[u]; i != -; i = query[i].next)
{
int v = query[i].q;
if (vis[v])
{
ans[query[i].index] = ancestor[find(v)];
}
}
}
bool in[maxn];
int main()
{
int T, n;
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
init(n);
memset(in, false, sizeof(in));
int u, v;
for (int i = ; i < n; i++)
{
scanf("%d %d", &u, &v);
in[v] = true;
addedge(u, v);
addedge(v, u);
}
scanf("%d %d", &u, &v);
addquery(u, v, Q);//添加查询
addquery(v, u, Q++);
int root;
for (int i = ; i <= n; i++)
{
if (!in[i])
{
root = i;
break;
}
}
LCA(root);
for (int i = ; i < Q; i++)//按照顺序打印出来答案
printf("%d\n", ans[i]);
}
return ;
}

RMQ&LCA在线模板:

RMQ st算法是用来求一段连续的区间最值问题的,如果将树看成一个线性结构,那么它可以快速求出一段区间的最值,那么就可以利用它求出LCA,首先求出一个树的欧拉序列(就是dfs序),然后每个节点都有深度,都有到根节点的距离。保存一个第一次访问到某个节点的编号。这样求两个点的LCA就是求从欧拉序列当中的一段到另外一段(连续的)深度的最小值。直接RMQ就可以了。模板如下:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm> using namespace std;
typedef long long ll;
const int maxn = ;
int tot, head[maxn];
struct Edge {
int to, next;
}edge[maxn];
int occur[maxn];
int first[maxn];
int dep[maxn];
bool vis[maxn];
int m;
void init()
{
tot = ;
memset(head, -, sizeof(head));
memset(vis, false, sizeof(vis));
memset(first, , sizeof(first));
m = ;
}
void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
void dfs(int u, int depth)
{
occur[++m] = u;
dep[m] = depth;
if (!first[u])
first[u] = m;
for (int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
dfs(v, depth + );
occur[++m] = u;
dep[m] = depth;
}
}
int Rmin[maxn * ][];
void RMQ(int n)
{
for (int i = ; i <= n; i++)
Rmin[i][] = i;
int k = (int)log2(n);
for (int j = ; j <= k; j++)
{
for (int i = ; i + ( << j) - <= n; i++)
Rmin[i][j] = dep[Rmin[i][j - ]] < dep[Rmin[i + ( << (j - ))][j - ]] ? Rmin[i][j - ] : Rmin[i + ( << (j - ))][j - ];
}
}
int query(int a, int b)
{
int l = first[a], r = first[b];
if (l > r)
swap(l, r);
int k = (int)log2(r - l + );
int tmp = dep[Rmin[l][k]] < dep[Rmin[r - ( << k) + ][k]] ? Rmin[l][k] : Rmin[r - ( << k) + ][k];
return occur[tmp];
}
int main()
{
int T, n;
scanf("%d", &T);
while (T--)
{
init();
scanf("%d", &n);
int a, b;
for (int i = ; i < n; i++)
{
scanf("%d %d", &a, &b);
addedge(a, b);
vis[b] = true;
}
int root;
for (int i = ; i <= n; i++)
{
if (!vis[i])
{
root = i;
break;
}
}
dfs(root, );
scanf("%d %d", &a, &b);
RMQ(m);
printf("%d\n", query(a, b));
}
return ;
}

POJ 1330 Nearest Common Ancestors(LCA模板)的更多相关文章

  1. POJ.1330 Nearest Common Ancestors (LCA 倍增)

    POJ.1330 Nearest Common Ancestors (LCA 倍增) 题意分析 给出一棵树,树上有n个点(n-1)条边,n-1个父子的边的关系a-b.接下来给出xy,求出xy的lca节 ...

  2. POJ 1330 Nearest Common Ancestors LCA题解

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19728   Accept ...

  3. poj 1330 Nearest Common Ancestors lca 在线rmq

    Nearest Common Ancestors Description A rooted tree is a well-known data structure in computer scienc ...

  4. poj 1330 Nearest Common Ancestors LCA

    题目链接:http://poj.org/problem?id=1330 A rooted tree is a well-known data structure in computer science ...

  5. POJ 1330 Nearest Common Ancestors (LCA,倍增算法,在线算法)

    /* *********************************************** Author :kuangbin Created Time :2013-9-5 9:45:17 F ...

  6. POJ - 1330 Nearest Common Ancestors(基础LCA)

    POJ - 1330 Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %l ...

  7. POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)

    POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...

  8. POJ 1330 Nearest Common Ancestors(lca)

    POJ 1330 Nearest Common Ancestors A rooted tree is a well-known data structure in computer science a ...

  9. POJ 1330 Nearest Common Ancestors 倍增算法的LCA

    POJ 1330 Nearest Common Ancestors 题意:最近公共祖先的裸题 思路:LCA和ST我们已经很熟悉了,但是这里的f[i][j]却有相似却又不同的含义.f[i][j]表示i节 ...

随机推荐

  1. 1s延时程序

    #include <reg52.h>sbit P1_0 = P1^0;void Delay(); // 下面引用时一定要和这里的大小写一致否则会有警告或错误 void Main(){whi ...

  2. openerp 产品图片的批量写入

    Write a short python script which loops over the image files, encode with base64 and write to OpenER ...

  3. BAE 环境下配置 struts2 + spring + hibernate(SSH)(三)spring&hibernate

    1.在lib中加入必要的包,导入后结果如下: lib打包下载:SSH-lib.jar  (struts2.3.1.2  spring3.0.5 hibernate3.6.10.Final) 只包含必要 ...

  4. CentOS 6.4编译安装淘宝web服务器Tengine

    Tengine 是由淘宝核心系统部基于Nginx开发的Web服务器,它在Nginx的基础上,针对大访问量网站的需求,添加了很多功能和特性.Tengine的性能和稳定性已经在大型的网站如淘宝网,淘宝商城 ...

  5. loadView与viewDidLoad不同 && loadView学习总结

    loadView学习总结 UIViewController类或其子类会在初始化时创建一个UIView对象,会作为控制器的默认视图显示出来,可以通过self.view寻址访问.但没有调用loadView ...

  6. 最新iOS 6 in Xcode4.5新特性——Storyboard和属性自动绑定

    最新iOS 6 in Xcode4.5新特性编程之二(上)——Storyboard和属性自动绑定 从Xcode 4.3开始,Storyboard 就是iOS 5和iOS 6中令人兴奋的一个新特性,他将 ...

  7. fix iis Running slow

    为什么写这个文章.因为我现在再找一个站点的访问原因..方法还是老方法.. 1. 站点是否真的挂了 a. 基本上全挂.所有请求非常缓慢或超时. b.大多数请求慢,但最终还是执行了.有可能 队列再排队 怎 ...

  8. hdu 5135 Little Zu Chongzhi's Triangles

    http://acm.hdu.edu.cn/showproblem.php?pid=5135 题意:给你N个木棍的长度,然后让你组成三角形,问你组成的三角形的和最大是多少? 思路:先求出可以组成的所有 ...

  9. 快速创建php server

    mkdir testmv test.html testphp -S localhost:8082http://localhost:8082/test.html

  10. 数据结构(树套树):ZJOI 2013 K大数查询

    有几个点卡常数…… 发现若第一维为位置,第二维为大小,那么修改时第一维修改区间,查询时第一维查询区间,必须挂标记.而这种情况下标记很抽象,而且Push_down不是O(1)的,并不可行. 那要怎么做呢 ...