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 ...
随机推荐
- POJ2112_Optimal Milking(网洛流最大流Dinic+最短路Flody+二分)
解题报告 农场有k个挤奶机和c头牛,每头牛到每一台挤奶机距离不一样,每台挤奶机每天最多挤m头牛的奶. 寻找一个方案,安排每头牛到某一挤奶机挤奶,使得c头牛须要走的全部路程中的最大路程的最小值. 要使每 ...
- JMS的样例
1.JMS是一个由AS提供的Message服务.它能接受消息产生者(Message Provider)所发出的消息,并把消息转发给消息消费者(Message Consumer).2.JMS提供2种类 ...
- C语言编写的bmp读写程序
C语言编写的bmp读写程序 建议先把bmp的数据存储格式了解下 <span style="font-size:16px;">#include "Windows ...
- BZOJ 2809 APIO2012 dispatching Treap+启示式合并 / 可并堆
题目大意:给定一棵树,选定一棵子树中的一些点,薪水和不能超过m,求点的数量*子树根节点的领导能力的最大值 考虑对于每一个节点,我们维护一种数据结构,在当中贪心寻找薪金小的雇佣. 每一个节点暴力重建一定 ...
- 灰度共生矩阵(GLCM) 及matlab代码实现
原地址:http://blog.csdn.net/bookwormno1/article/details/7962466 这几天学习灰度共生矩阵,现记录如下: 讲灰度共生矩阵比较好的一份百度文库文档: ...
- Socket简介 (转)
Socket小白篇-附加TCP/UDP简介 Socket 网络通信的要素 TCP和UDP Socket的通信流程图 1.Socket 什么是Socket Socket:又称作是套接字,网络上的两个程序 ...
- Android基于发展Service音乐播放器
这是一个基于Service组件的音乐播放器,程序的音乐将会由后台的Service组件负责播放,当后台的播放状态改变时,程序将会通过发送广播通知前台Activity更新界面:当用户单击前台Activit ...
- c++一些语法模板
函数模板特 template <class T> int compare(T v1,T v2) { if(v1<v2) return -1; else if(v1>v2) re ...
- Unobtrusive Ajax
ASP.NET MVC之Unobtrusive Ajax(五) 前言 这一节我们来讲讲Unobtrusive中的Ajax提交,大部分情况下我们是利用JQuery来进行Ajax请求,当然利用JQue ...
- NGUI研究之在Unity中使用贝塞尔曲线
鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天由于工作的原因须要将贝塞尔曲线加在project中.那么我迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的随意角度的曲线,这两个点一 ...