POJ 1330 Nearest Common Ancestors (最近公共祖先LCA + 详解博客)
LCA问题 详细
1、二叉搜索树上找两个节点LCA
public int query(Node t, Node u, Node v) {
int left = u.value;
int right = v.value; //二叉查找树内,如果左结点大于右结点,不对,交换
if (left > right) {
int temp = left;
left = right;
right = temp;
} while (true) {
//如果t小于u、v,往t的右子树中查找
if (t.value < left) {
t = t.right; //如果t大于u、v,往t的左子树中查找
} else if (t.value > right) {
t = t.left;
} else {
return t.value;
}
}
}
2、二叉树上找两个节点
node* getLCA(node* root, node* node1, node* node2)
{
if(root == null)
return null;
if(root== node1 || root==node2)
return root; node* left = getLCA(root->left, node1, node2);
node* right = getLCA(root->right, node1, node2); if(left != null && right != null) // 两个点在root的左右两边,就是root了
return root;
else if(left != null) // 哪边不空返回哪边
return left;
else if (right != null)
return right;
else
return null;
}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
const int Max = ;
int t, n, first, second, root;
vector<int> G[Max];
int indegree[Max], depth[Max], father[Max];
void inputTree()
{
for (int i = ; i <= n; i++)
{
G[i].clear();
father[i] = ;
indegree[i] = ;
depth[i] = ;
}
int u, v;
for (int i = ; i < n; i++)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
indegree[v]++;
father[v] = u;
}
scanf("%d%d", &first, &second);
for (int i = ; i <= n; i++)
{
if (indegree[i] == )
{
root = i;
break;
}
}
}
void dfs_depth(int u, int dep)
{
depth[u] = dep;
int Size = G[u].size();
for (int i = ; i < Size; i++)
{
dfs_depth(G[u][i], dep + );
}
}
int find_ancestor()
{
while (depth[first] > depth[second])
{
first = father[first];
}
while (depth[first] < depth[second])
{
second = father[second];
}
while (first != second) // 这样直接返回first
{
first = father[first];
second = father[second];
}
return first;
}
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
inputTree();
dfs_depth(root, );
printf("%d\n", find_ancestor());
}
return ;
}
tarjan + 并查集 解法:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
const int Max = ;
int t, n, first, second, root;
vector<int> G[Max], querry[Max];
int indegree[Max], father[Max], vis[Max];
void inputTree()
{
for (int i = ; i <= n; i++)
{
G[i].clear();
querry[i].clear();
father[i] = i;
indegree[i] = ;
vis[i] = ;
}
int u, v;
for (int i = ; i < n; i++)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
indegree[v]++;
}
scanf("%d%d", &first, &second);
querry[first].push_back(second);
querry[second].push_back(first);
for (int i = ; i <= n; i++)
{
if (indegree[i] == )
{
root = i;
break;
}
}
}
int find_father(int x)
{
if (x == father[x])
return x;
return father[x] = find_father(father[x]);
}
void unionSet(int x, int y)
{
x = find_father(x);
y = find_father(y);
if (x != y)
father[y] = x;
}
void tarjan(int x)
{
int Size = G[x].size();
for (int i = ; i < Size; i++)
{
int v = G[x][i];
tarjan(v);
unionSet(x, v);
}
vis[x] = ;
/*
if (x == first && vis[second])
printf("%d\n", find_father(second));
else if (x == second && vis[first])
printf("%d\n", find_father(first));
*/
Size = querry[x].size();
for (int i = ; i < Size; i++)
{
if (vis[querry[x][i]])
{
printf("%d\n", find_father(querry[x][i]));
return;
}
} }
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
inputTree();
tarjan(root);
}
return ;
}
POJ 1330 Nearest Common Ancestors (最近公共祖先LCA + 详解博客)的更多相关文章
- POJ - 1330 Nearest Common Ancestors 最近公共祖先+链式前向星 模板题
A rooted tree is a well-known data structure in computer science and engineering. An example is show ...
- 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 ——最近公共祖先(LCA)
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18136 Accept ...
- poj 1330 Nearest Common Ancestors 求最近祖先节点
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 37386 Accept ...
- POJ 1330 Nearest Common Ancestors(Targin求LCA)
传送门 Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 26612 Ac ...
- POJ 1330 Nearest Common Ancestors (模板题)【LCA】
<题目链接> 题目大意: 给出一棵树,问任意两个点的最近公共祖先的编号. 解题分析:LCA模板题,下面用的是树上倍增求解. #include <iostream> #inclu ...
- 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)
POJ - 1330 Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %l ...
- POJ.1330 Nearest Common Ancestors (LCA 倍增)
POJ.1330 Nearest Common Ancestors (LCA 倍增) 题意分析 给出一棵树,树上有n个点(n-1)条边,n-1个父子的边的关系a-b.接下来给出xy,求出xy的lca节 ...
随机推荐
- GWT-Dev-Plugin(即google web toolkit developer plugin)for firefox的下载地址
如果FireFox的版本为20,则对应google-web-toolkit的插件离线下载地址,不要用浏览器直接下载,用Flashget等客户端下载,超快. http://google-web-tool ...
- Web软件安全攻击
- Linux企业集群用商用硬件和免费软件构建高可用集群PDF
Linux企业集群:用商用硬件和免费软件构建高可用集群 目录: 译者序致谢前言绪论第一部分 集群资源 第1章 启动服务 第2章 处理数据包 第3章 编译内容 第二部分 高可用性 第4章 使用rsync ...
- useradd 添加用户
功能介绍 useradd命令用于Linux中创建的新的系统用户.useradd可用来建立用户帐号.帐号建好之后,再用passwd设定帐号的密码.而可用userdel删除帐号.使用useradd指令所建 ...
- ecshop 签名
先从index.php主页开始 页面关键字 {$keywords } 页面标题 {$page_title} 产品分类 父分类列表 {foreach from=$categories item=cat ...
- mysql union和union all的区别
union 对两个结果集进行并集操作,重复数据只显示一次 Union All,对两个结果集进行并集操作,重复数据全部显示 工具/原料 mysql 数据库 方法/步骤 student表数据 使用 ...
- Dubbo系列(2)_RPC介绍
一.本文目的 主要介绍RPC的一些概念和应用. 二.为什么要介绍RPC DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治 ...
- ES6新特性:Javascript中的Map和WeakMap对象
Map对象 Map对象是一种有对应 键/值 对的对象, JS的Object也是 键/值 对的对象 : ES6中Map相对于Object对象有几个区别: 1:Object对象有原型, 也就是说他有默认的 ...
- jquery- pagination使用
$("#gupiaopage").page({ showInfo: false, showJump: false, showPageSizes: true, firstBtnTex ...
- SurfaceView, TextureView, SurfaceTexture等的区别
SurfaceView, GLSurfaceView, SurfaceTexture以及TextureView是Android当中名字比较绕,关系又比较密切的几个类.本文基于Android 5.0(L ...