LCA问题的tarjan解法模板

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;
}
朴素法求解: 先对树进行dfs标出每一个节点的深度,对于查找的两个点先判断在不在同一深度,不在 移到统一深度,然后在往上找
 #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 + 详解博客)的更多相关文章

  1. POJ - 1330 Nearest Common Ancestors 最近公共祖先+链式前向星 模板题

    A rooted tree is a well-known data structure in computer science and engineering. An example is show ...

  2. POJ 1330 Nearest Common Ancestors 倍增算法的LCA

    POJ 1330 Nearest Common Ancestors 题意:最近公共祖先的裸题 思路:LCA和ST我们已经很熟悉了,但是这里的f[i][j]却有相似却又不同的含义.f[i][j]表示i节 ...

  3. 【POJ】1330 Nearest Common Ancestors ——最近公共祖先(LCA)

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18136   Accept ...

  4. poj 1330 Nearest Common Ancestors 求最近祖先节点

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 37386   Accept ...

  5. POJ 1330 Nearest Common Ancestors(Targin求LCA)

    传送门 Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26612   Ac ...

  6. POJ 1330 Nearest Common Ancestors (模板题)【LCA】

    <题目链接> 题目大意: 给出一棵树,问任意两个点的最近公共祖先的编号. 解题分析:LCA模板题,下面用的是树上倍增求解. #include <iostream> #inclu ...

  7. POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)

    POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...

  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 (LCA 倍增)

    POJ.1330 Nearest Common Ancestors (LCA 倍增) 题意分析 给出一棵树,树上有n个点(n-1)条边,n-1个父子的边的关系a-b.接下来给出xy,求出xy的lca节 ...

随机推荐

  1. GWT-Dev-Plugin(即google web toolkit developer plugin)for firefox的下载地址

    如果FireFox的版本为20,则对应google-web-toolkit的插件离线下载地址,不要用浏览器直接下载,用Flashget等客户端下载,超快. http://google-web-tool ...

  2. Web软件安全攻击

  3. Linux企业集群用商用硬件和免费软件构建高可用集群PDF

    Linux企业集群:用商用硬件和免费软件构建高可用集群 目录: 译者序致谢前言绪论第一部分 集群资源 第1章 启动服务 第2章 处理数据包 第3章 编译内容 第二部分 高可用性 第4章 使用rsync ...

  4. useradd 添加用户

    功能介绍 useradd命令用于Linux中创建的新的系统用户.useradd可用来建立用户帐号.帐号建好之后,再用passwd设定帐号的密码.而可用userdel删除帐号.使用useradd指令所建 ...

  5. ecshop 签名

    先从index.php主页开始 页面关键字 {$keywords } 页面标题 {$page_title} 产品分类 父分类列表 {foreach from=$categories item=cat ...

  6. mysql union和union all的区别

    union 对两个结果集进行并集操作,重复数据只显示一次 Union All,对两个结果集进行并集操作,重复数据全部显示 工具/原料 mysql 数据库 方法/步骤   student表数据   使用 ...

  7. Dubbo系列(2)_RPC介绍

    一.本文目的         主要介绍RPC的一些概念和应用. 二.为什么要介绍RPC    DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治 ...

  8. ES6新特性:Javascript中的Map和WeakMap对象

    Map对象 Map对象是一种有对应 键/值 对的对象, JS的Object也是 键/值 对的对象 : ES6中Map相对于Object对象有几个区别: 1:Object对象有原型, 也就是说他有默认的 ...

  9. jquery- pagination使用

    $("#gupiaopage").page({ showInfo: false, showJump: false, showPageSizes: true, firstBtnTex ...

  10. SurfaceView, TextureView, SurfaceTexture等的区别

    SurfaceView, GLSurfaceView, SurfaceTexture以及TextureView是Android当中名字比较绕,关系又比较密切的几个类.本文基于Android 5.0(L ...