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

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. python unicode&str 转化

    从数据库中取出的值是Unicode编码的 需要转化为str才能正常使用 参考: http://www.mamicode.com/info-detail-308445.html

  2. Lua 5.1 for Delphi 2010

    This is a Lua 5.1 Wrapper for Delphi 2009 and Delphi 2010 which automatically creates OOP callback f ...

  3. frame,bounds,center-三者的含义

    frame与bounds的区别比较 frame,bounds,center-三者的含义 偶然觉的,这三个属性有时候定位的时候,需要用.于是就来搞清楚,到底frame,bounds,center 这三个 ...

  4. 【Java】WebService教程

    Web Services Web Services可以将应用程序转换为网络应用程序. Web Services可以被其他应用程序利用. 基本的Web Services平台是XML + HTTP. WS ...

  5. IllegalArgumentException: Does not contain a valid host:port authority: master:8031

    java.lang.IllegalArgumentException: Does not contain a valid host:port authority: master:8031 (confi ...

  6. Ubuntu_10.04下Hadoop-0.20.2集群配置手册

    Ubuntu_10.04下Hadoop-0.20.2集群配置手册 一.软硬件环境的准备 下面的文章来自hadoopor.com,我先交待一下我自己的环境: 两台机器,每台机器上面两个虚机(vmware ...

  7. Iphone6 LightBlue测试BT4GMD-Q25P透传模块

    安装LightBlue后,连接透传模块之后,显示如下: 注意:0xFF01是写通道,0xFF02是读通道 BLE透传模块与PL2303相连,在PC端用串口调试助手显示数据. 一.lightblue向B ...

  8. Android Wear开发 - 卡片通知 - 第二节 : 自定义Wear卡片样式

    一.前言说明 在上一节添加Android Wear通知特性我们实现了简单的Android Wear卡片拓展,但是默认提供给我们的多张卡片只能实现简单的文字展示,如果想要自定义布局,添加图片等等,则需要 ...

  9. The fundamental knowledge of Node JS.

    D3 JSJava scirpt is an awesome language for Internface Design.All Obejcts in JavaScirpt could be use ...

  10. Squares(哈希)

    Time Limit: 3500MS   Memory Limit: 65536K Total Submissions: 14328   Accepted: 5393 Description A sq ...