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. Oracle查询排序asc/desc 多列 order by

    查询结果的排序 显示EMP表中不同的部门编号. 如果要在查询的同时排序显示结果,可以使用如下的语句: SELECT 字段列表 FROM 表名 WHERE 条件 ORDER BY 字段名1 [ASC|D ...

  2. 关于React的赋值与调用方法

    #关于React的赋值与调用方法 比如调用方法的时候我们可以这样来使用closeFrm() <div className = "infoFrm_close" onMouseO ...

  3. 屏幕旋转时 Activity 的生命周期 —— 测试与结论

    关于 Android 手机横竖屏切换时 Activity 的生命周期问题,网上有很多相似的文章,大多数都是说明在竖屏切换横屏时 Activity 会重启一次,而在横屏切换竖屏时 Activity 会重 ...

  4. 分布式系统中的CAP原理和BASE理论

    CAP是一致性(Consistency).可用性(Availability).分区容忍性(Partition tolerance)的缩写.CAP原理指的是这三个要素最多只能同时实现两点,不可能三者兼顾 ...

  5. 洛谷 2543 [AHOI2004]奇怪的字符串

    题目描述 输入输出格式 输入格式: 输入文件中包含两个字符串X和Y.当中两字符串非0即1.序列长度均小于9999. 输出格式: X和Y的最长公共子序列长度. 输入输出样例 输入样例#1: 010101 ...

  6. codevs 3344 迷宫

    时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题目描述 Description 小刚在迷宫内,他需要从A点出发,按顺序经过B,C,D……,到达最后一个点,再回到A ...

  7. js 判断是什么浏览器、是否为谷歌浏览器

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http ...

  8. JS计算两个日期时间差,天 小时 分 秒格式

    function diffTime(startDate,endDate) { startDate= new Date(startDate); endDate = new Date(endDate); ...

  9. 3d点云

    rgb-d:rgb加depth组成4channel的 3d点云

  10. numpy.random.randint

    low.high.size三个参数.默认high是None,如果只有low,那范围就是[0,low).如果有high,范围就是[low,high). >>> np.random.ra ...