【POJ1330】Nearest Common Ancestors(树链剖分求LCA)
Description
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 5Sample Output
4
3
【题意】
就是求两个点的最近公共祖先。 【分析】
这题可以用倍增做,这次我用了树剖,感觉还挺好打的,嗯嗯...
感觉是因为不可能跳两条重链都越过LCA,因为一个点向下只连一条重边。所以每次调dep较大的边跳就好了。
int LCA(int a, int b)
{
while (1)
{
if(top[a]==top[b]) return dep[a]<=dep[b]?a:b;
else if(dep[top[a]]>=dep[top[b]]) a=fa[top[a]];
else b=fa[top[b]];
}
}
就是这样。
感觉是因为不可能跳两条边都越过LCA的,因为一个点向下只连着一条重边,所以我们每次选短的那一条跳就好了。
http://www.xuebuyuan.com/552070.html
这里有详细证明^^^
代码如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 10010
#define INF 100000000 int fa[Maxn],first[Maxn],size[Maxn],dep[Maxn],son[Maxn];
int w[Maxn],top[Maxn];int wl;
bool q[Maxn]; struct node
{
int x,y,next;
}t[*Maxn];int len; int mymax(int x,int y) {return x>y?x:y;}
int mymin(int x,int y) {return x<y?x:y;} void ins(int x,int y)
{
t[++len].x=x;t[len].y=y;
t[len].next=first[x];first[x]=len;
} void dfs1(int x,int f)
{
fa[x]=f;dep[x]=dep[f]+;size[x]=;
son[x]=;
for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
{
dfs1(t[i].y,x);
size[x]+=size[t[i].y];
if(size[t[i].y]>size[son[x]]) son[x]=t[i].y;
}
} void dfs2(int x,int tp)
{
w[x]=++wl;
top[x]=tp;
if(size[x]!=) dfs2(son[x],tp);
for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x]&&t[i].y!=son[x])
{
dfs2(t[i].y,t[i].y);
}
} int LCA(int a, int b)
{
while ()
{
if(top[a]==top[b]) return dep[a]<=dep[b]?a:b;
else if(dep[top[a]]>=dep[top[b]]) a=fa[top[a]];
else b=fa[top[b]];
}
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
memset(first,,sizeof(first));
memset(q,,sizeof(q));
len=;
for(int i=;i<n;i++)
{
int x,y,c;
scanf("%d%d",&x,&y);
q[y]=;
ins(x,y);//ins(y,x);
}
int root;
for(int i=;i<=n;i++) if(!q[i]) root=i;
dep[]=;size[]=;
dfs1(root,);wl=;
dfs2(root,);
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",LCA(x,y));
}
return ;
}
[POJ1330]
2016-05-08 17:13:07
【POJ1330】Nearest Common Ancestors(树链剖分求LCA)的更多相关文章
- 树链剖分求LCA
树链剖分中各种数组的作用: siz[]数组,用来保存以x为根的子树节点个数 top[]数组,用来保存当前节点的所在链的顶端节点 son[]数组,用来保存重儿子 dep[]数组,用来保存当前节点的深度 ...
- cogs 2450. 距离 树链剖分求LCA最近公共祖先 快速求树上两点距离 详细讲解 带注释!
2450. 距离 ★★ 输入文件:distance.in 输出文件:distance.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] 在一个村子里有N个房子,一 ...
- cogs 2109. [NOIP 2015] 运输计划 提高组Day2T3 树链剖分求LCA 二分答案 差分
2109. [NOIP 2015] 运输计划 ★★★☆ 输入文件:transport.in 输出文件:transport.out 简单对比时间限制:3 s 内存限制:256 MB [题 ...
- HDU2586 How far away ? (树链剖分求LCA)
用树链剖分求LCA的模板: 1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 const ...
- 【树链剖分】洛谷P3379 树链剖分求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 【模板】树链剖分求LCA
洛谷3379 #include<cstdio> #include<algorithm> using namespace std; ,inf=1e9; int n,m,x,y,r ...
- Hdu 2586 树链剖分求LCA
Code: #include<cstdio> #include<cstring> #include<vector> #include<algorithm> ...
- POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)
POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...
- Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分)
Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分) Description L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之 ...
随机推荐
- AOP 的利器:ASM 3.0 介绍
引言 什么是 ASM ? ASM 是一个 Java 字节码操控框架.它能被用来动态生成类或者增强既有类的功能.ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态 ...
- centos7安装chrome的历程(fedora同)
安装 首先是下载,地址奉上:http://www.google.cn/chrome/browser/desktop/index.html,选择64 bit .rpm (适用于 Fedora/openS ...
- skip-grant-tables
1.net stop mysql 2.my.ini中[mysqld]plugin_dir的下面增加skip-grant-tables 3.net start mysql 4.在Navicat中打开my ...
- 学习使用Et采集的过程和分析
- Sqlserver通过链接服务器访问Oracle的解决办法
转自http://blog.sina.com.cn/s/blog_614b6f210100t80r.html 一.创建sqlserver链接服务(sqlserver链接oracle) 首先sqlse ...
- A题笔记(3)
No. 1381 容器相关 #include <vector> 头文件 vector<Presents> present; present.push_back(name); 向 ...
- C语言malloc()函数:动态分配内存空间
头文件:#include <stdlib.h> malloc() 函数用来动态地分配内存空间(如果你不了解动态内存分配,请查看:C语言动态内存分配及变量存储类别),其原型为:void* m ...
- Script: Who’s using a database link?(找出谁在使用dblink)
Every once in awhile it is useful to find out which sessions are using a database link in an Oracle ...
- ios 设置label的高度随着内容的变化而变化
好吧 步骤1:创建label _GeRenJianJie = [[UILabel alloc]init]; 步骤2:设置label _GeRenJianJie.textColor = RGBAColo ...
- 1 Winform 异步更新控件
刚才看到有人问为了winfrom中,在大数据绑定的时候出现画面假死的状态,为了解决这个问题希望通过再开一个线程来给控件绑定数据,可是画面还是会假死.现在看到的方法有1.掩耳盗铃法(Control.Ch ...