题目链接:http://poj.org/problem?id=1330

A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:

In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree. Node x is an ancestor of node y if node x is in the path between the root and node y. For example, node 4 is an ancestor of node 16. Node 10 is also an ancestor of node 16. As a matter of fact, nodes 8, 4, 10, and 16 are the ancestors of node 16. Remember that a node is an ancestor of itself. Nodes 8, 4, 6, and 7 are the ancestors of node 7. A node x is called a common ancestor of two different nodes y and z if node x is an ancestor of node y and an ancestor of node z. Thus, nodes 8 and 4 are the common ancestors of nodes 16 and 7. A node x is called the nearest common ancestor of nodes y and z if x is a common ancestor of y and z and nearest to y and z among their common ancestors. Hence, the nearest common ancestor of nodes 16 and 7 is node 4. Node 4 is nearer to nodes 16 and 7 than node 8 is.

For other examples, the nearest common ancestor of nodes 2 and 3 is node 10, the nearest common ancestor of nodes 6 and 13 is node 8, and the nearest common ancestor of nodes 4 and 12 is node 4. In the last example, if y is an ancestor of z, then the nearest common ancestor of y and z is y.

Write a program that finds the nearest common ancestor of two distinct nodes in a tree. 

题意描述:在一个DAG中,定义节点u是节点v的祖先:节点u是树根到节点v的路径上的一个节点。 给出一些节点之间的关系,求出两个节点的最近公共祖先。

算法分析:最近公共祖先(LCA)的入门题。

最近公共祖先算法的大致思路:

1:求出每个节点的2^k(0<=k<max_log_n)的祖先节点。节点u的2^0(第一代)祖先节点就是u的父亲节点,那么我们可以得到u的第一代、第二代、第四代、第八代...祖先节点。

2:把节点u和v深度大的节点根据1中的算法思想移到和深度小的节点同一深度(树根深度为0,树根的儿子节点深度为1),然后再一起往上移,即可求出LCA。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector>
#define inf 0x7fffffff
using namespace std;
const int maxn=+;
const int max_log_maxn=; int n,A,B,root;
vector<int> G[maxn];
int father[max_log_maxn][maxn],d[maxn]; void dfs(int u,int p,int depth)
{
father[][u]=p;
d[u]=depth;
int num=G[u].size();
for (int i= ;i<num ;i++)
{
int v=G[u][i];
if (v != father[][u]) dfs(v,u,depth+);
}
} void init()
{
dfs(root,-,);
for (int k= ;k+<max_log_maxn ;k++)
{
for (int i= ;i<=n ;i++)
{
if (father[k][i]<) father[k+][i]=-;
else father[k+][i]=father[k][father[k][i] ];
}
}
} int LCA()
{
if (d[A]<d[B]) swap(A,B);
for (int k= ;k<max_log_maxn ;k++)
{
if ((d[A]-d[B])>>k & )
{
A=father[k][A];
}
}
if (A==B) return A;
for (int k=max_log_maxn- ;k>= ;k--)
{
if (father[k][A] != father[k][B])
{
A=father[k][A];
B=father[k][B];
}
}
return father[][A];
} int main()
{
int t;
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
for (int i= ;i<=n ;i++) G[i].clear();
for (int i= ;i<max_log_maxn ;i++)
{
for (int j= ;j<maxn ;j++)
father[i][j]=-;
}
int a,b;
int vis[maxn];
memset(vis,,sizeof(vis));
for (int i= ;i<n- ;i++)
{
scanf("%d%d",&a,&b);
G[a].push_back(b);
vis[b]=;
}
scanf("%d%d",&A,&B);
for (int i= ;i<=n ;i++) if (!vis[i]) {root=i;break; }
init();
printf("%d\n",LCA());
}
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,倍增算法,在线算法)

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

  5. POJ 1330 Nearest Common Ancestors(LCA模板)

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

  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. 【转】详解JavaScript中的this

    ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...

  2. Winform开发常用控件之Checkbox和CheckedListBox

    Winform的开发基本都是基于控件事件的,也就是事件驱动型的. 多选框的放置和值的获取有很多种,这里介绍几个简单常用的方法 1.直接放置Checkbox,并获取Checkbox的值 上图 做法也非常 ...

  3. Centos 7配置ntp时间同步

    1.NTP时钟同步方式说明     NTP在linux下有两种时钟同步方式,分别为直接同步和平滑同步: 1)直接同步      使用ntpdate命令进行同步,直接进行时间变更.如果服务器上存在一个1 ...

  4. Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException:

    七月 17, 2014 4:56:01 下午 org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service( ...

  5. reader,字符流

    1. public class Demo1 { public static void main(String[] args) throws IOException { File file = new ...

  6. uboot启动流程

    uboot 的启动过程及工作原理2.1 启动模式介绍    大多数 Boot Loader 都包含两种不同的操作模式:"启动加载"模式和"下载"模式,这种区别仅 ...

  7. linuxok6410的I2C驱动分析---用户态驱动

    3  i2c-dev 3.1 概述 之前在介绍I2C子系统时,提到过使用i2c-dev.c文件在应用程序中实现我们的I2C从设备驱动.不过,它实现的是一个虚拟,临时的i2c_client,随着设备文件 ...

  8. EMVTag系列10《发卡行公钥证书》

    Ø  90  发卡行公钥(IPK)证书 L: NCA -C(有条件):如果支持SDA,DDA CA认证过的发卡行公钥.用于脱机数据认证 Ø  9F32    发卡行公钥指数 L: 1 or 3 -C( ...

  9. linux 下的使用 ln 创建 软链接 和 硬链接

    linux 下的一个指令 ln 作用: 创建软链接或者硬链接 Linux 系统下每创建一个文件,系统都会为此文件生成一个 index node 简称(inode) ,而每一个文件都包含用户数据(use ...

  10. hdu 1908 Double Queue

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1908 Double Queue Description The new founded Balkan ...