LCA 学习算法 (最近的共同祖先)poj 1330
Nearest Common Ancestors
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 20983 | Accepted: 11017 |
Description
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
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
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
在求解近期公共祖先为问题上,用到的是Tarjan的思想,从根结点開始形成一棵深搜树。处理技巧就是在回溯到结点u的时候。u的子树已经遍历。这时候才把u结点放入合并集合中,这样u结点和全部u的子树中的结点的近期公共祖先就是u了,u和还未遍历的全部u的兄弟结点及子树中的近期公共祖先就是u的父亲结点。
这样我们在对树深度遍历的时候就非常自然的将树中的结点分成若干的集合,两个集合中的所属不同集合的随意一对顶点的公共祖先都是同样的,也就是说这两个集合的近期公共祖先仅仅有一个。时间复杂度为O(n+q),n为节点,q为询问节点对数。
#include"stdio.h"
#include"string.h"
#include"vector"
using namespace std;
#define N 11000
const int inf=1<<20;
vector<int>g[N];
int s,t,n;
int f[N],pre[N],ans[N];
bool vis[N];
int findset(int x)
{
if(x!=f[x])
f[x]=findset(f[x]);
return f[x];
}
int unionset(int a,int b)
{
int x=findset(a);
int y=findset(b);
if(x==y)
return x;
f[y]=x;
return x;
}
void lca(int u)
{
int i,v;
ans[u]=u;
for(i=0;i<g[u].size();i++)
{
v=g[u][i]; //訪问由父节点引出的各个子节点
lca(v);
int x=unionset(u,v); //把父子节点合并
ans[x]=u; //祖先节点记为U
}
vis[u]=1;
if(u==s&&vis[t]) //两个节点依次被訪问标记,第二次訪问时才满足条件
{
printf("%d\n",ans[findset(t)]);
return ;
}
else if(u==t&&vis[s])
{
printf("%d\n",ans[findset(s)]);
return ;
}
}
int main()
{
int i,u,v,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
{
pre[i]=-1; //记录节点I的父节点
f[i]=i; //并查集记录根节点
vis[i]=0;
g[i].clear();
}
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
g[u].push_back(v);
pre[v]=u;
}
scanf("%d%d",&s,&t);
for(i=1;i<=n;i++)
if(pre[i]==-1)
break;
lca(i);
}
return 0;
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
LCA 学习算法 (最近的共同祖先)poj 1330的更多相关文章
- [最近公共祖先] POJ 1330 Nearest Common Ancestors
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 27316 Accept ...
- POJ 1330 Nearest Common Ancestors (LCA,倍增算法,在线算法)
/* *********************************************** Author :kuangbin Created Time :2013-9-5 9:45:17 F ...
- POJ 1330 Nearest Common Ancestors 倍增算法的LCA
POJ 1330 Nearest Common Ancestors 题意:最近公共祖先的裸题 思路:LCA和ST我们已经很熟悉了,但是这里的f[i][j]却有相似却又不同的含义.f[i][j]表示i节 ...
- POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)
POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...
- POJ 1330 Nearest Common Ancestors (LCA,dfs+ST在线算法)
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14902 Accept ...
- POJ - 1330 Nearest Common Ancestors(dfs+ST在线算法|LCA倍增法)
1.输入树中的节点数N,输入树中的N-1条边.最后输入2个点,输出它们的最近公共祖先. 2.裸的最近公共祖先. 3. dfs+ST在线算法: /* LCA(POJ 1330) 在线算法 DFS+ST ...
- 最近公共祖先LCA(Tarjan算法)的思考和算法实现
LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...
- 最近公共祖先 LCA 倍增算法
树上倍增求LCA LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 ...
- POJ 1986 Distance Queries (Tarjan算法求最近公共祖先)
题目链接 Description Farmer John's cows refused to run in his marathon since he chose a path much too lo ...
随机推荐
- 编程算法 - 萨鲁曼的军队(Saruman's Army) 代码(C)
萨鲁曼的军队(Saruman's Army) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 直线上有N个点, 每个点, 其距离为R以内的区域里 ...
- OCA读书笔记(15) - 执行数据库备份
物理备份 -- 数据文件,控制文件,日志文件,参数文件 数据库备份 冷备 -- 归档和非归档均可以 什么时候必须用冷备?1. 数据库的模式为非归档的2. 用于现场保护 冷备的过程:1. 首先查看备份文 ...
- projecteuler---->problem=9----Special Pythagorean triplet
title: A Pythagorean triplet is a set of three natural numbers, a b c, for which, a2 + b2 = c2 For e ...
- 阿里2016实习offer五面经验与总结(转)
前言 目前楼主已经拿到阿里实习offer,一共经历了5次面试,其中4轮技术面,1轮HR面试.在这里分享一下自己的面试经验和学习总结.写这篇面经主要是希望能够帮助更多的小伙伴.我本科毕业于中南大学信管专 ...
- hdu2569(递推dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2569 分析: f(n),n个珠子的合格数:a(n),n个珠子,最后2个相同的合格数:b(n),n个珠子 ...
- android 项目中使用对话框统一封装
近期在做拼车项目中使用到了一些对话框,而且在非常多地方都使用到了,既然非常多地方使用到,那么肯定要封装一下,
- HTTP协议中的短轮询、长轮询、长连接和短连接
HTTP协议中的短轮询.长轮询.长连接和短连接 引言 最近刚到公司不到一个月,正处于熟悉项目和源码的阶段,因此最近经常会看一些源码.在研究一个项目的时候,源码里面用到了HTTP的长轮询.由于之前没太接 ...
- 调用WCF的异步方法
原文:调用WCF的异步方法 AsyncCallback aLoginCallback = delegate(IAsyncResult result) { var aSystemUser = WcfCl ...
- HYSBZ 2243(树链剖分)
题目连接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/D 题意:给定一棵有n个节点的无根树及点权和m个操作, ...
- hdu1166(线段树)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 线段树功能:update:单点增减 query:区间求和 #pragma comment(lin ...