首页 > 其他分享 >51nod2599 最近公共祖先LCA

51nod2599 最近公共祖先LCA

时间:2024-03-19 22:34:37浏览次数:26  
标签:dep 51nod2599 fa 祖先 cin dfs int LCA adj

给定一颗n个节点的树,根节点编号为1,有Q组询问,每次给定一对节点编号(x,y),求(x,y)的最近公共祖先。

求LCA有多种方法,这里给的是倍增法,预处理时间O(nlogn),单次查询时间O(logn),支持在线。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=b;i>=a;i--)

const int N = 500005;
int n, Q, dep[N], fa[N][21];
vector<int> adj[N];

void dfs(int x, int p) {
    fa[x][0] = p;
    dep[x] = dep[p] + 1;
    rep(i,1,20) {
        fa[x][i] = fa[fa[x][i-1]][i-1];
    }
    for (auto i:adj[x]) if (i!=p) {
        dfs(i, x);
    }
}
int lca(int x, int y) {
    if (dep[x] < dep[y]) swap(x, y);
    per(i,0,20) if (dep[fa[x][i]] >= dep[y]) {
        x = fa[x][i];
    }
    if (x == y) return x;
    per(i,0,20) if (fa[x][i] != fa[y][i]) {
        x = fa[x][i];
        y = fa[y][i];
    }
    return fa[x][0];
}

void solve() {
    cin >> n;
    rep(i,1,n-1) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 1);
    cin >> Q;
    while (Q--) {
        int a, b;
        cin >> a >> b;
        cout << lca(a,b) << "\n";
    }
}

signed main() {
    cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

标签:dep,51nod2599,fa,祖先,cin,dfs,int,LCA,adj
From: https://www.cnblogs.com/chenfy27/p/18084129

相关文章

  • AcWing 1171. 距离 Tarjan算法离线求LCA
    题目输入样例1:22121001221输出样例1: 100100输入样例2:32121031151232输出样例2: 1025LCA算法:LCA(LeastCommonAncestors)最近公共祖先Tarjan求LCA是一种离线的算法,也就是说它一遍求出所有需要求的点的LCA,而不是需要求哪两个点再去求......
  • 代码随想录 第22天 | ● 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入
    leetcode:701.二叉搜索树中的插入操作-力扣(LeetCode)classSolution{publicTreeNodeinsertIntoBST(TreeNoderoot,intval){//判断叶子结点,null说明到了,可以赋值。if(root==null){TreeNodenode=newTreeNode(val);return......
  • 货车运输(LCA+最大生成树)
    货车运输这题会有重边,又因为求的是尽可能大的边中的最小值,所以我们可以先用最大生成树维护,如何用最大生成树呢?可以用Kruskal和并查集,顺便处理重边,处理完重边后,可以用倍增LCA求两点之间的最大载重量处理重边时,必须把dis在x,y相同情况下大的排在前,以保证最优,用并查集find判断是否......
  • 大都市meg(线段树/树状数组+LCA)
    题目描述在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员BlueMary也开始骑着摩托车传递邮件了。不过,她经常回忆起以前在乡间漫步的情景。昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双向的土路。从每个村庄都恰好有一条路径到达村庄1(即比特堡)。并且......
  • P4211 [LNOI2014] LCA 题解
    link切入这道题,首先要思考所有LCA的分布特征。显然,对于任意\(\text{LCA}(i,j)\),都满足LCA是\(i,j\)的祖先。那么对于一个询问,可以找到所有\(i\in[l,r]\)的祖先,还可以找所有\(z\)的祖先。明显,找\(z\)的祖先会方便很多:它们都分布在\(z\)到根节点的那条链上,这应......
  • 代码随想录 第21天 | ● 530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ●
    leetcode:530.二叉搜索树的最小绝对差-力扣(LeetCode)思路:判断最小绝对差,肯定用中序遍历,双指针一前一后依次判断。classSolution{intresult=Integer.MAX_VALUE;TreeNodepre=null;publicintgetMinimumDifference(TreeNoderoot){if(root==......
  • 图论——倍增LCA 学习笔记
    图论——倍增LCA学习笔记定义最近公共祖先,简称LCA(LowestCommonAncestor)。一个集合\(S\)的最近公共祖先\(\text{LCA}(S)=\text{LCA}(s_1,s_2,\dots,s_k)\)定义为:这个集合中所有节点,其祖先的交集中,离根最远的那个。性质在数值的关系上:\(\text{LCA}(\{u\})=u\);\(\t......
  • 236. 二叉树的最近公共祖先c
    /***Definitionforabinarytreenode.*structTreeNode{*intval;*structTreeNode*left;*structTreeNode*right;*};*/structTreeNode*lowestCommonAncestor(structTreeNode*root,structTreeNode*p,structTreeNode*q){......
  • 2024-03-13:用go语言,给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 输
    2024-03-13:用go语言,给定一个二叉搜索树,找到该树中两个指定节点的最近公共祖先。输入:root=[6,2,8,0,4,7,9,null,null,3,5],p=2,q=8。输出:6。答案2024-03-13:来自左程云。灵捷3.5大体步骤如下:1.首先,我们需要遍历树来找到这两个节点。从根节点开始,若两个节点都比......
  • 代码随想录算法训练营day21 | leetcode 530. 二叉搜索树的最小绝对差、501. 二叉搜索
    目录题目链接:530.二叉搜索树的最小绝对差-简单题目链接:501.二叉搜索树中的众数-简单题目链接:236.二叉树的最近公共祖先-中等题目链接:530.二叉搜索树的最小绝对差-简单题目描述:给你一个二叉搜索树的根节点root,返回树中任意两不同节点值之间的最小差值。差值是一个正数,......