专栏文章

P3379 板子 倍增和tarjan求Lca

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqaduxd
此快照首次捕获于
2025/12/04 01:34
3 个月前
此快照最后确认于
2025/12/04 01:34
3 个月前
查看原文
倍增:
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,s;
int head[N],nxt[N],to[N],cnt;
int deep[N],fa[N][25];
void add(int u,int v){
	nxt[++cnt]=head[u];
	head[u]=cnt;
	to[cnt]=v;
	return ;
}
void dfs(int x,int father){
	deep[x]=deep[father]+1;
	fa[x][0]=father;
	for(int i=1;(1<<i)<=deep[x];i++)	fa[x][i]=fa[fa[x][i-1]][i-1];	//(1<<i)<=deep[x]
	for(int i=head[x];i;i=nxt[i])	if(to[i]!=father) dfs(to[i],x);		//if(to[i]!=father)
}
int lca(int x,int y){
	if(deep[x]<deep[y]) swap(x,y);
	for(int i=24;i>=0;i--)	if(deep[x]-(1<<i)>=deep[y]) x=fa[x][i];		//(deep[x]-(1<<i) >= deep[y])
	if(x==y) return x;
	for(int i=24;i>=0;i--)	if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
	return fa[x][0];
}
int main(){
	scanf("%d%d%d",&n,&m,&s);
	int a,b;
	for(int i=1;i<n;i++){
		scanf("%d%d",&a,&b);
		add(a,b),add(b,a);
	}	
	dfs(s,0);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&a,&b);
		printf("%d\n",lca(a,b));
	}
	return 0;
}
tarjan:
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m,s;
int head[N],nxt[N],to[N],cnt;
int head_query[N],nxt_query[N],to_query[N],num_query[N],cnt_query;
int vis[N],fa[N];
int ans[N];
inline int read(){
	register int x=0;register char s=getchar();
	while(s<'0'||s>'9') s=getchar();
	while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
	return x;
}
void add(int u,int v){nxt[++cnt]=head[u],head[u]=cnt,to[cnt]=v;}
void add_query(int u,int v,int num){
	nxt_query[++cnt_query]=head_query[u];
	head_query[u]=cnt_query;
	to_query[cnt_query]=v;
	num_query[cnt_query]=num;
}
int find(int a){return fa[a]==a?a:fa[a]=find(fa[a]);}
void tarjan(int root){
	vis[root]=1;
	for(register int i=head[root];i;i=nxt[i]){
		register int v=to[i];
		if(!vis[v]){
			tarjan(v);
			fa[v]=root;
		}
	}
	for(register int i=head_query[root];i;i=nxt_query[i]){
		register int v=to_query[i];
		if(vis[v])	ans[num_query[i]]=find(v);
	}
}
signed  main(){
	n=read(),m=read(),s=read();
	register int a,b;
	for(register int i=1;i<n;++i){
		fa[i]=i;
		a=read(),b=read();
		add(a,b),add(b,a);
	}
	fa[n]=n;
	
	for(register int i=1;i<=m;++i){
		a=read(),b=read();
		add_query(a,b,i),add_query(b,a,i);
	}
	
	tarjan(s);
	for(register int i=1;i<=m;++i) printf("%d\n",ans[i]);
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...