A. Nearest Common Ancestors

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 10000KB
 
64-bit integer IO format: %lld      Java class name: Main
 
 
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.

 

Input

The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case starts with a line containing an integer N , the number of nodes in a tree, 2<=N<=10,000. The nodes are labeled with integers 1, 2,..., N. Each of the next N -1 lines contains a pair of integers that represent an edge --the first integer is the parent node of the second integer. Note that a tree with N nodes has exactly N - 1 edges. The last line of each test case contains two distinct integers whose nearest common ancestor is to be computed.

 

Output

Print exactly one line for each test case. The line should contain the integer that is the nearest common ancestor.

 

Sample Input

2
16
1 14
8 5
10 16
5 9
4 6
8 4
4 10
1 13
6 15
10 11
6 7
10 2
16 3
8 1
16 12
16 7
5
2 3
3 4
3 1
1 5
3 5
 

Sample Output

4
3 解题:本来打算用dfs+RMQ写的,结果写得一塌糊涂,完全不对。后来发现只有一个询问,即为了这一次询问可以破坏原有结构。直接暴力好了。
 #include <iostream>
#include <cstdio>
using namespace std;
bool vis[];
int uf[];
int main() {
int ks,n,i,x,y;
scanf("%d",&ks);
while(ks--) {
scanf("%d",&n);
for(i = ; i <= n; i++) {
vis[i] = false;
uf[i] = i;
}
for(i = ; i < n; i++) {
scanf("%d %d",&x,&y);
uf[y] = x;
}
scanf("%d %d",&x,&y);
vis[x] = true;
x = uf[x];
while(x != uf[x]) {
vis[x] = true;
x = uf[x];
}
while(y != uf[y]) {
if(vis[y]) break;
y = uf[y];
}
printf("%d\n",y);
}
return ;
}

倍增法求LCA

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <vector>
#include <queue>
#include <cstdlib>
#include <string>
#include <set>
#include <stack>
#define LL long long
#define pii pair<int,int>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = ;
int n,deep[maxn],fa[maxn][];
vector<int>g[maxn];
void dfs(int u,int f){
for(int i = ; i < g[u].size(); i++){
if(g[u][i] == f) continue;
deep[g[u][i]] = deep[u]+;
dfs(g[u][i],u);
}
}
void init(){
for(int j = ; j < ; j++){
for(int i = ; i <= n; i++)
fa[i][j] = fa[fa[i][j-]][j-];
}
}
int LCA(int u,int v){
if(deep[u] < deep[v]) swap(u,v);
int i,d = deep[u]-deep[v];
for(i = ; i < ; i++) if((<<i)&d) u = fa[u][i];
if(u == v) return u;
for(i = ; i >= ; i--){
if(fa[u][i] != fa[v][i]){
u = fa[u][i];
v = fa[v][i];
}
}
return fa[u][];
}
int main() {
int t,i,u,v,root;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i = ; i <= n; i++){
g[i].clear();
deep[i] = ;
}
memset(fa,,sizeof(fa));
for(i = ; i < n; i++){
scanf("%d %d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
fa[v][] = u;
if(!fa[u][]) root = u;
}
deep[root] = ;
dfs(root,-);
init();
scanf("%d %d",&u,&v);
printf("%d\n",LCA(u,v));
}
return ;
}

tarjan求LCA

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <vector>
#include <queue>
#include <cstdlib>
#include <string>
#include <set>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = ;
vector<int>g[maxn];
int n,x,y,uf[maxn],ans;
bool vis[maxn];
int Find(int rt) {
if(rt != uf[rt])
uf[rt] = Find(uf[rt]);
return uf[rt];
}
bool dfs(int u) {
uf[u] = u;
for(int i = ; i < g[u].size(); i++) {
if(!vis[g[u][i]]) {
if(dfs(g[u][i])) return true;
uf[g[u][i]] = u;
}
}
if(u == x && vis[y]) {
ans = Find(y);
return true;
} else if(u == y && vis[x]) {
ans = Find(x);
return true;
}
vis[u] = true;
return false;
}
int main() {
int t,i,u,v,root;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(i = ; i <= n; i++) {
g[i].clear();
vis[i] = false;
}
for(i = ; i < n; i++) {
scanf("%d %d",&u,&v);
g[u].push_back(v);
vis[v] = true;
}
for(i = ; i <= n; i++)
if(!vis[i]) {
root = i;
break;
}
scanf("%d%d",&x,&y);
memset(vis,false,sizeof(vis));
dfs(root);
cout<<ans<<endl;
}
return ;
}

A. Nearest Common Ancestors的更多相关文章

  1. POJ 1330 Nearest Common Ancestors(Targin求LCA)

    传送门 Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26612   Ac ...

  2. [最近公共祖先] POJ 1330 Nearest Common Ancestors

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

  3. POJ 1330 Nearest Common Ancestors

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

  4. POJ1330 Nearest Common Ancestors

      Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24587   Acce ...

  5. POJ 1330 Nearest Common Ancestors(Tree)

    题目:Nearest Common Ancestors 根据输入建立树,然后求2个结点的最近共同祖先. 注意几点: (1)记录每个结点的父亲,比较层级时要用: (2)记录层级: (3)记录每个结点的孩 ...

  6. 【POJ】1330 Nearest Common Ancestors ——最近公共祖先(LCA)

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

  7. POJ 1330 Nearest Common Ancestors LCA题解

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

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

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

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

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

  10. pku 1330 Nearest Common Ancestors LCA离线

    pku 1330 Nearest Common Ancestors 题目链接: http://poj.org/problem?id=1330 题目大意: 给定一棵树的边关系,注意是有向边,因为这个WA ...

随机推荐

  1. SQL server函数

    一般在开发中用到的函数 标量函数用的比较多 标量函数:就是返回一个单一的结果值 下面介绍一下标量函数的语法 create function GetFunction  --创建函数 (   @name ...

  2. 【R语言进行数据挖掘】决策树和随机森林

    1.使用包party建立决策树 这一节学习使用包party里面的函数ctree()为数据集iris建立一个决策树.属性Sepal.Length(萼片长度).Sepal.Width(萼片宽度).Peta ...

  3. mount_cd9660:/dev/acd0: Input/output error

    mount -t cd9660 /dev/acd0 /cdrom g_vfs_done():acd0[READ(offset32768, length=204]error =5 mount_cd966 ...

  4. Postgres远程访问配置

    在服务器上安装了Postgres数据库,然后通过客户端工具pgAdminIII来远程访问的过程中发现提醒服务器没有启动监听的错误.解决方法如下: 编辑Postgres安装路径下的/data/pg_hb ...

  5. Perl sendmail

    introduction of sendmail example send mail to multi-receiver

  6. COGS 2082. Asm.Def谈笑风生

    ★   输入文件:asm_talk.in   输出文件:asm_talk.out   简单对比时间限制:2 s   内存限制:256 MB [题目描述] “人呐都不知道,自己不可以预料,直升机刚一出圣 ...

  7. Linux OpenGL 实践篇-14-多实例渲染

    多实例渲染 OpenGL的多实例渲染是一种连续执行多条相同的渲染命令的方法,并且每条命令产生的结果都有轻微的差异,通常用于渲染大量的几何物体. 设想一个场景,比如太空,我们需要渲染数以万记的星球,如果 ...

  8. UVA1663 Purifying Machine (匈牙利算法,二分图最大匹配)

    模版集合个数减少是因为匹配串集合中没被匹配过的一对串匹配了.所以就是找一个二分图最大匹配. 因为集合X和Y是不好分开的,但是可以直接跑,两个集合都会跑一遍,所以一个匹配会被算两次,返回的时候除以2就行 ...

  9. Django ORM 查询操作

    queryset中支持链式操作 book=Book.objects.all().order_by('-nid').first() 只要返回的是queryset对象就可以调用其他的方法,直到返回的是对象 ...

  10. Dance links算法

    其实Dance links只是一种数据结构,Dance links 才是一种算法.dacing links x就是一个高效的求解该类问题的算法,而这种算法,基于交叉十字循环双向 链表.下面是双向十字链 ...