首页 > 其他分享 >最近公共祖先(LCA)

最近公共祖先(LCA)

时间:2024-07-14 21:31:23浏览次数:10  
标签:dep 20 Soup 祖先 LCA int 公共 最右

https://www.luogu.com.cn/problem/P7103


第4题     最近公共祖先 查看测评数据信息

小 Soup 正在翻看他们家的族谱,他们家的族谱构成了一棵树。小 Soup 发现,由于年代久远,他们家族中的一些分支已经绝迹,他对此十分好奇。

小 Soup 给你他们家的族谱树,想要问你在这棵树中所有第 k 层的孩子(树中深度为 k 的点,根节点的深度为 1 ,根节点编号为 1 )的最近公共祖先是谁。

输入格式

 

第一行两个整数 n,m。  

第二行 n 个整数,其中第 i 个整数为 f[i],表示 i 的父亲为 f[i],请注意,1 的 f[i] 固定为 0。  

接下来 m 行,每行一个整数 k,代表小 Soup 的询问。

%20 n[1,10],m[1,10]

%20 n[1,100],m[1,100]

%20 n[1,1000],m[1,1000]

%20 n[1,100000],m[1,100000]

%20 n[1,5000000],m[1,5000000]

 

 

输出格式

 

对于每个小 Soup 的询问,输出一个整数,即所有深度为 k 的点的最近公共祖先。

 

输入/输出例子1

输入:

8 3

0 1 1 2 2 3 4 5

2

1

4

 

输出:

1

1

2

 

样例解释

 

 

两个思路

1.记录每层中最左,最右的节点,找最左最右最近公共祖先  ( 缺证)
2.自底向上bfs,记录所有答案

 

这里只讨论第一种。

关于最左最右很好整,最左是dfs中最先到的那个点,最右是dfs中最后到的那个点,分别记录即可。

#include <bits/stdc++.h>
using namespace std;
const int N=100005;

int n, m, x, k, vis[N], dep[N], first[N], last[N];
int f[N][25];
vector<int> a[N];
void dfs(int u, int fa)
{
	if (vis[u]) return ;
	vis[u]=1;
	
	dep[u]=dep[fa]+1;
	
	f[u][0]=fa;
	for (int i=1; (1<<i)<=dep[u]; i++)
		f[u][i]=f[f[u][i-1]][i-1];
	
	if (!first[dep[u]]) first[dep[u]]=u;
	last[dep[u]]=u;
	
	for (int i=0; i<a[u].size(); i++)
	{
		int v=a[u][i];
		if (v!=fa) dfs(v, u);
	}
}
int lca(int x, int y)
{
	if (dep[x]<dep[y]) swap(x, y);
	
	for (int i=24; i>=0; i--)
		if (dep[f[x][i]]>=dep[y]) x=f[x][i];
		
	if (x==y) return x;
	
	for (int i=24; i>=0; i--)
		if (f[x][i]!=f[y][i]) x=f[x][i], y=f[y][i];
	
	return f[x][0];
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i=1; i<=n; i++) 
	{
		scanf("%d", &x);
		a[x].push_back(i);
		a[i].push_back(x);
	}
	
	dep[1]=1;
	dfs(1, 0);
	
	while (m--)
	{
		scanf("%d", &k);
		printf("%d\n", lca(first[k], last[k]));
	}
	return 0;
}

  

 

 

标签:dep,20,Soup,祖先,LCA,int,公共,最右
From: https://www.cnblogs.com/didiao233/p/18302037

相关文章

  • Acwin-3692. 最长连续公共子序列——待续
    1.题目输入两个字符串s1,s2。输出最长连续公共子串长度和最长连续公共子串。输入格式一行,两个字符串s1,s2,用空格隔开。输出格式第一行输出最长连续公共子串的长度第二行输出最长连续公共子串。如果不唯一,则输出s1中的最后一个。数据范围1≤|s1|,|s2|≤100数据保证......
  • 最近公共祖先——AcWing 356. 次小生成树
    最近公共祖先定义最近公共祖先(LowestCommonAncestor,LCA)是在一棵有根树中,对于两个节点u和v,LCA是所有公共祖先中深度最大的一个节点。换句话说,LCA是u 和v的共同祖先中距离根节点最远的一个。运用情况最短路径问题:在树中,求两节点间的最短路径,可以先找到它们的LCA,......
  • 帝国CMS网站通过自定义扩展变量功能,用户可以自定义公共的程序使用变量,为用户扩展系统
    通过自定义扩展变量功能,用户可以自定义公共的程序使用变量,为用户扩展系统带来便利。比如可以增加像系统$public_r[newsurl]这样的变量,还比如扩展了某个系统模型,需要增加设置项都可以用扩展变量来实现...等等。 一、登录后台,单击“系统”菜单,选择“扩展变量”......
  • luoguP3533 lca
    [POI2012]RAN-Rendezvous题目描述ByteasarisarangerwhoworksintheArrowCave-afamousrendezvousdestinationamonglovers.Thecaveconsistsof\(n\)chambersconnectedwithone-waycorridors.Ineachchamberexactlyoneoutgoingcorridorismarked......
  • 公共资源管理服务中心智能化方案PPT(97页)
    公共资源管理服务中心智能化方案摘要1.建设背景及需求公共资源管理服务中心的建设以便民、高效、廉洁、规范为宗旨,推行“一站式办公、一条龙服务、并联式审批、阳光下作业、规范化管理”的运行模式。目标是提高行政效率和社会效益,预防流程漏洞,加强多重监管,实现阳光操作,建立......
  • vue js公共截取URL的key: value方法
    letURL=http://localhost:8080/#/ficu/?taskid=1001-2271023&pageId=146&ssid=74529457205982&channelld=IPCC&userId=xx//取值URLlethref=window.location.href//拿到完整的URLlethash=window.location.hash//取#后面的所有URL//取值方法getUrlPara......
  • vue 混合方法mixins 协可以写入公共的方法
    新建一个文件夹mixins 同views同级exportdefault{data(){return{};},mounted(){},methods:{//修改标题方法ready(callback){//如果jsbridge已经注入则直接调用if(window.AlipayJSBridge){callback......
  • layui js thymeleaf 公共工具类
    layuijsthymeleaf公共工具类其中功能包括:普通表格渲染树形表格渲染普通编辑(添加/删除/编辑)更多编辑(添加/编辑/更多)上传图片constcommon={getTable(table,url,cols,condition){if(!condition||condition==''){condition=......
  • 代码随想录day20 二叉搜索树的最近公共祖先 | 二叉搜索树中的插入操作 | 删除二叉
    二叉搜索树的最近公共祖先二叉搜索树的最近公共祖先解题思路利用二叉搜索树的特性,公共祖先的值,就是在要找的两个值的区间里面知识点二叉搜索树心得想了一会如何利用二叉搜索树的特性。顺便复习了昨天做的题目二叉搜索树中的插入操作二叉搜索树中的插入操作解题思路在......
  • Day 47 | 1143.最长公共子序列 、 53. 最大子序和
    1143.最长公共子序列体会一下本题和718.最长重复子数组的区别视频讲解:https://www.bilibili.com/video/BV1ye4y1L7CQhttps://programmercarl.com/1143.最长公共子序列.html给定两个字符串text1和text2,返回这两个字符串的最长公共子序列的长度。一个字符串的子序列是......