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. 前端页面,使用 dom 鼠标拖拽画一个矩形和监听键盘

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  2. AJPFX简述i=i+1与i+=1及x++的区别和效率

    i=i+1与i+=1及x++的区别和效率 1.x=x+1,x+=1及x++的效率哪个最高?为什么? x=x+1最低,因为它的执行如下. (1)读取右x的地址: (2)x+1: (3)读取左x的地址: ...

  3. Spring MVC 入门实例报错404的解决方案

    若启动服务器控制台报错,并且是未找到xml配置文件,初始化DispatchServlet失败,或者控制台未报错404,那么: 1.URL的排查: 格式-----------协议名://地址:端口号/上 ...

  4. cvLoadImage,cvCloneImage的内存泄露问题

    本文转自: http://hi.baidu.com/%C3%A8%D1%DB%D3%E3/blog/item/9d947e1b2b05555742a9adfd.html/cmtid/9872c2260 ...

  5. Android 如何利用Activity的Dialog风格完成弹出框设计

    在我们使用Dialog时,如果需要用到很多自己设计的控件,虽然可以让弹出框显示出我们需要的界面,但却无法找到地方完成控制代码的编写,如何解决这个问题呢,我们可以将Activity伪装成Dialog弹出 ...

  6. ReactiveCocoa 响应式函数编程

    简介 ReactiveCocoa(简称为RAC),RAC具有函数响应式编程特性,由Matt Diephouse开源的一个应用于iOS和OS X的新框架. 为什么使用RAC? 因为RAC具有高聚合低耦合 ...

  7. SP2-0734: 未知的命令开头 "imp scott/..." - 忽略了剩余的行。

    Oracle数据导入报错:SP2-0734: 未知的命令开头 "imp scott/..." - 忽略了剩余的行. 原因:进入sqlplus里是不能执行imp的(sqlplus不认 ...

  8. 忘记Centos7.2下root用户密码后的处理方式

    1)重启系统 重新启动系统后并按f2键,进入如下的界面,再按e键. 2)修改启动内核代码 在代码的linux16行中,将ro rhgb的ro修改为rw init=/sysroot/bin/sh. 3) ...

  9. Redis学习笔记(一)五种数据类型

    1.字符串(String) 基本操作:SET(设置).GET(获取).DEL(删除)其他操作传送门 root@localhost:~# redis-cli > set msg hello OK ...

  10. java 核心技术卷一笔记 6 .1.接口 lambda 表达式 内部类

    6.1.2 接口不是类,不能实例化一个接口:但是可以声明接口的变量:Comparable x;    接口变量必须引用实现了接口的类对象:x = new Employee(); 检查一个对象是否属于某 ...