zoukankan      html  css  js  c++  java
  • 学习笔记:树剖求 LCA

    我之前介绍过 tarjan 求 LCA 的方法:链接-->戳我!
    然而离线算法又长又臭,果真烦人,于是我们尝试用树剖解决问题。
    我们联想暴力求 LCA 的方法,发现在跳父亲的时候有一些点可以一下子跳过去。
    而树剖便是把链们作为一个整体,由于 (top) 数组的存在,直接跳到 (f_{top}) 即可。
    复杂度容易证明是 (mathcal O((n+m)log n)),常数比倍增小,不算很难写(至少我一遍 (A)

    (Code):

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    
    #define read(x) scanf("%d",&x)
    #define MAXN 500005
    
    int top[MAXN],dep[MAXN],son[MAXN],f[MAXN],tot[MAXN];
    struct node
    {
    	int to,nxt;
    }e[MAXN<<1];
    int head[MAXN],cnt=0;
    int n,m,root,l,r;
    
    void add(int u,int v)
    {
    	e[++cnt].to=v;
    	e[cnt].nxt=head[u];
    	head[u]=cnt;
    }
    
    int dfsa(int cur,int deep)
    {
    	dep[cur]=deep;
    	tot[cur]=1;
    	son[cur]=0;
    	int maxn=0;
    	for(int i=head[cur];i;i=e[i].nxt)
    	{
    		int j=e[i].to;
    		if(j==f[cur]) continue;
    		f[j]=cur;
    		int now=dfsa(j,deep+1);
    		if(now>maxn) maxn=now,son[cur]=j;
    		tot[cur]+=now;
    	}
    	return tot[cur];
    }
    
    void dfsb(int cur,int topf)
    {
    	top[cur]=topf;
    	if(son[cur]) dfsb(son[cur],topf);
    	for(int i=head[cur];i;i=e[i].nxt)
    	{
    		int j=e[i].to;
    		if(top[j]) continue;
    		dfsb(j,j);
    	}
    	return;
    }
    
    int lca(int x,int y)
    {
    	while(top[x]!=top[y])
    	{
    		if(dep[top[x]]<dep[top[y]]) swap(x,y);
    		x=f[top[x]];
    	}
    	return dep[x]<dep[y]?x:y;
    }
    
    int main()
    {
    	read(n),read(m),read(root);
    	for(int i=1;i<n;i++)
    	{
    		read(l),read(r);
    		add(l,r),add(r,l);
    	}
    	f[root]=root;
    	dfsa(root,1);
    	dfsb(root,root);
    	for(int i=1;i<=m;i++)
    	{
    		read(l),read(r);
    		printf("%d
    ",lca(l,r));
    	}	
    	return 0; 
    }
    
  • 相关阅读:
    游吟诗人阿严
    学霸女
    sql group by 分组后查询最新的一条数据
    腐朽
    我喜欢不说话的山川
    redis启动
    php 时间轴,数据统计(最近7天的数据)
    php options 请求跨域
    mac关机声音
    JVM-内存模型
  • 原文地址:https://www.cnblogs.com/tlx-blog/p/12799698.html
Copyright © 2011-2022 走看看