ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

tarjan法求LCA学习笔记

2022-02-08 08:00:34  阅读:146  来源: 互联网

标签:tarjan 遍历 int cz LCA 节点 法求


tarjan求LCA

前言

tarjan求LCA的时间复杂度是\(O(n+2*q)\),是非常优秀的复杂度,但缺点就是只能离线。(懂了,去学欧拉序\(O(1)\)求LCA)

tarjan求LCA需要用到并查集,本人用的代码:

int f[N];
void cz(int x){return x==f[x]?x:f[x]=cz(f[x]);}
void hb(int x,int y){f[cz(x)]=cz(y);}

tarjan查找到LCA后直接输出,如果无需输出,就要用数组先存储。

正文

思想

首先,树上两个点的LCA有两种可能,一种是其中的一个点,一种同是属于另一个点的子树内。
tarjan算法的思想是DFS遍历每一个节点,用并查集记录其之间的父子关系。

操作

当遍历到某个节点\(x\)时:

  1. 标记当前节点为已访问节点。
  2. 递归遍历其所有子节点\(y\),并用并查集合并。
  3. 遍历与当前与当前节点有查询关系的结点(称之为\(z\))(即是需要查询LCA的另一些结点),如果\(z\)已经访问,那么\(x\)与\(z\)的LCA就是\(cz(z)\)(查找函数),输出或者记录下来就可以了。

代码:

LCA模板题

#include <bits/stdc++.h>
#define P push_back
#define M make_pair
using namespace std;
const int N=1e6;
int n,q,rt,vis[N],f[N],ans[N],cnt,fir[N];
vector <pair<int,int> >ask[N];
int cz(int x){return f[x]==x?x:f[x]=cz(f[x]);}
struct edge{int v,nt;}e[N<<1];void add(int u,int v){e[++cnt].v=v;e[cnt].nt=fir[u];fir[u]=cnt;}
void dfs(int u,int fa)
{
    vis[u]=1;f[u]=u;
    for(int i=fir[u];i;i=e[i].nt)
        if(e[i].v!=fa)
        {
            dfs(e[i].v,u);
            f[e[i].v]=u;
        }
    for(int i=0;i<ask[u].size();i++)
        if(vis[ask[u][i].second]==1)    ans[ask[u][i].first]=ask[u][i].second;
        else if(vis[ask[u][i].second])  ans[ask[u][i].first]=cz(ask[u][i].second);
    vis[u]=2;
}
int main()
{
    cin>>n>>q>>rt;for(int i=1;i<=n;i++)f[i]=i;
    for(int i=1,u,v;i<n;i++)
    {
        cin>>u>>v;
        add(u,v);add(v,u);
    }
    for(int i=1,x,y;i<=q;i++)
    {
        cin>>x>>y;
        ask[x].P(M(i,y));
        ask[y].P(M(i,x));
    }
    dfs(rt,0);for(int i=1;i<=q;i++)cout<<ans[i]<<endl;return 0;
}

标签:tarjan,遍历,int,cz,LCA,节点,法求
来源: https://www.cnblogs.com/AIskeleton/p/15869478.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有