首页 > 其他分享 >tarjan求LCA

tarjan求LCA

时间:2024-08-25 19:18:14浏览次数:7  
标签:tarjan int 合并 LCA include 节点

题面

如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。

思路

这次我们要使用的知识点是 \(dfs\) 和并查集,这个 \(tarjan\) 是离线的,我们要先把每个点的每一个要跟它求 \(LCA\) 的点给记录下来,接下来用 \(dfs\) 跑这么个流程:

  1. 遍历这个点的每个子结点并进入子节点
  2. 将子节点与自己合并
  3. 遍历要跟它求 \(LCA\) 的点,如果这个点被访问了,这个点在并查集中的祖先便是答案

等等,你是不是蒙圈了?我们先放张图:

假设我们要求 \(LCA(3,6)\) 。

我们在这张图上模拟一下并查集中的过程:

首先,一切还是一盘散沙:

接下来,\(3\) 和它的父节点 \(4\) 合并起来了,由于与 \(3\) 它相关联的 \(6\) 还没访问,此时无法更新任何答案:

接着又是 \(5,4\) 以及 \(2,5\),都无法更新答案:

注意了!!!此处敲黑板!!!此时我们访问到 \(2\) 的另一个子节点 \(6\),此时我们便发现,\(3\) 已被访问,于是答案是 \(2\) !!!

后面的无用功就不放了。

于是,我们就发现了,其实我们就是把点按 \(dfn\) 序不断合并,当两个点要合并在一起时,此时的祖先便是答案,就像这样:

\(x\) 和 \(y\) 便是要求 \(LCA\) 的两个点,它们现在刚好就合并到一起,显然只有到它们的公共祖先它们才会合并在一起,再由于回溯时是从深到低,所以第一次合并在一起时一定是到 \(LCA\) 了。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdio>
#include<string>
#include<iomanip>
using namespace std;
const int N=5e5+10;
int n,m,s;
struct edge{
	int to,nxt;
}g[N<<1];
int head[N],tot1=0;
struct qry{
	int to,nxt,idx;
}q[N<<1];
int qhead[N],tot2=0;
int ans[N];
void add(int x,int y){
	tot1++;
	g[tot1].to=y;
	g[tot1].nxt=head[x];
	head[x]=tot1;
	return;
}
void qadd(int x,int y,int z){
	tot2++;
	q[tot2].to=y;
	q[tot2].nxt=qhead[x];
	q[tot2].idx=z;
	qhead[x]=tot2;
	return;
}
int fa[N],vis[N];
int Find(int x){
	return (fa[x]==x)?x:(fa[x]=Find(fa[x]));
}
void dfs(int u,int f){
	vis[u]=1;
	for(int i=head[u];i;i=g[i].nxt){
		int v=g[i].to;
		if(v!=f){
			dfs(v,u);
			fa[v]=u;
		}
	}
	for(int i=qhead[u];i;i=q[i].nxt){
		int v=q[i].to;
		if(vis[v]){
			ans[q[i].idx]=Find(v);
		}
	}
	return;
}
int main(){
    cin.tie(0);
	ios::sync_with_stdio(false);
	cin>>n>>m>>s;
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	for(int i=1;i<=m;i++){
		int u,v;
		cin>>u>>v;
		qadd(u,v,i);
		qadd(v,u,i);
	}
	for(int i=1;i<=n;i++)fa[i]=i;
	dfs(s,0);
	for(int i=1;i<=m;i++){
		cout<<ans[i]<<"\n";
	}
	cout<<flush;
    return 0;
}

标签:tarjan,int,合并,LCA,include,节点
From: https://www.cnblogs.com/pengdave/p/18379357

相关文章

  • YOLOv8改进系列,YOLOv8添加MLCA注意力机制(混合局部信道注意)
    原论文摘要注意力机制是计算机视觉中最广泛使用的组件之一,能够帮助神经网络突出重要元素并抑制不相关的部分。然而,大多数通道注意力机制只包含通道特征信息,忽略了空间特征信息,导致模型的表示效果较差或目标检测性能不佳,并且空间注意力模块往往复杂且代价高昂。为了在性能......
  • Tarjan 之 割点 学习笔记
    首先,要求割点,我们需要知道割点是什么割点:是指在无向连通图中,如果删除某个顶点后,图的连通分量增加,则称该顶点为割点好,知道了这个,那我们怎么去求他呢?Tarjan大神给出了一种依然基于时间戳的算法图片来源:董晓算法割点的求法大概就是这样的所以细节还是见代码吧#include<bit......
  • Tarjan 之 SCC 与 缩点
    这篇文章将讲述作者对Tarjan求SCC与缩点(不是割点)的理解让我们开始吧!TarjanSCC与缩点既然要求\(SCC\)那我们先要弄明白什么是SCCSCC指的是强连通分量强连通指的是若一张有向图的节点两两互相可达,则这张图是强连通的而强连通分量指的是一个极大的连通子图此处的极......
  • tarjan之LCA学习笔记
    tarjan之LCA学习笔记tarjan算法求LCA可谓是一个极其巧妙的离线算法其本质是利用DFS遍历时产生的DFS序和并查集来在线性的时间复杂度内求出所有询问的结果既然是离线算法,其和在线算法的区别就在与离线算法需要记录下所有查询,对查询进行一定操作来得到更高的效率,而这......
  • 【Tarjan缩点】USACO5.3 校园网Network of Schools】
    [P2746USACO5.3]校园网NetworkofSchools大意:一个图可能有环a:求deg入度为0的点的个数b:至少加多少条边让图所有点可以互相到达思路:看代码#include<cstdio>#include<queue>#include<deque>#include<stack>#include<map>#include<cmath>#include<algorit......
  • LCA(最近公共祖先)
    参考博客:最近公共祖先算法详解之最近公共祖先(LCA)瓶颈生成树Tarjan算法#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintN=5e5+10;usingi64=longlong;intn,m,s;vector<int>g[N];vector<pair<int,int>>q[N];boolst[N];intp[N......
  • 【树上点差分、LCA】Max Flow P
    核心思路[USACO15DEC]MaxFlowP-洛谷sum[u]++,sum[v]++,sum[lca(u,v)]--,sum[fa[lca(u,v)]];本质上就是,对树进行差分自底向上进行统计处理#include<bits/stdc++.h>usingnamespacestd;intn,m;constintN=200000+10;vector<int>G[N];intdep[N],fa[N],hs......
  • 强连通分量tarjan
    引言强连通分量本质上是处理一个有向有环图(如果在这样的图上搞事情可能会死循环)变成一个有向无环图强连通分量上的点可以互相到达所以针对一些问题(我也没搞明白究竟是哪种问题)例如:给你一张有向图,每个点都有一个点权(不是边权了哦),且每一个点都可以经过任意多次,但是点权只......
  • 【Tarjan SCC 加边使得所有图联通 至少选取多少个点能图联通 】Network of Schools加
    [P2812校园网络【USACO]NetworkofSchools加强版大意:1.图G=(V,E)选几个点可以到达所有的点2.连多少条边可以让任意一个点出发到达其他所有点1思路:1.Tarjan跑一遍求SCC那些出度为0的点就是出发的所有点即din0的点的数量2.计算dout0的点的数量和din0的点的数量取max......
  • Acetylcarnitine 是一种内源性代谢产物 |MedChemExpress (MCE)
    CAS:14992-62-2品牌:MedChemExpress(MCE)存储条件:4°C,protectfromlight,storedundernitrogen*Insolvent:-80°C,6months;-20°C,1month(protectfromlight,storedundernitrogen)生物活性:Acetylcarnitine是一种内源性代谢产物。 参考详情:Acetylcarni......