• ST表求LCA整理


    我们知道有很多种求LCA的方法,比如直接暴力向上跳求取LCA,倍增求LCA,还有tarjan求LCA(我不会),以及ST表求LCA

    ST表求LCA的最大优点是预处理过后每次询问的复杂度是 (O(1)) 的,这非常的优秀。

    在求LCA的过程中,ST表起到的还是一个查询区间最小值的操作,并不是什么奇奇怪怪的运用,请放心食用。

    主要思路是我们给在dfs中经过的所有点都给予一个dfs序,当然,非叶子节点会被给予多个dfs序。我们按照dfs序将节点排序,得到一个数列,非叶子节点会多次出现。

    我们将点的编号换成他最小的dfs序,又得到了一个序列。我们设 (pre[u])(u) 的最小dfs序,(pos[s]) 为dfs序为s的节点编号,我们求出来c为dfs序区间 (pre[u])(pre[v]) 之间的最小值,那么 (pos[c]) 即为他们的LCA。

    洛谷P3376:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    int read()
    {
    	int a = 0,x = 1;
    	char ch = getchar();
    	while(ch > '9' || ch < '0'){
    		if(ch == '-') x = -1;
    		ch = getchar();
    	}
    	while(ch >= '0' && ch <= '9'){
    		a = a*10 + ch-'0';
    		ch = getchar();
    	}
    	return a*x;
    }
    const int N=1e6+7;
    int n,m,s;
    
    int head[N],go[N],nxt[N],cnt;
    void add(int u,int v)
    {
    	go[++cnt] = v;
    	nxt[cnt] = head[u];
    	head[u] = cnt;
    }
    int arr[N],pre[N],pos[N],fa[N][31],dis[N];
    void dfs(int u)
    {
    	++cnt;
    	arr[cnt] = cnt;
    	pre[u] = cnt,pos[cnt] = u;
    	for(int e = head[u];e;e = nxt[e]){
    		int v = go[e];
    		if(v == fa[u][0]) continue;
    		dis[v] = dis[u]+1;
    		fa[v][0] = u;
    		dfs(v);
    		arr[++cnt] = pre[u];
    	}
    }
    
    int st[N][31],lg[N];
    
    int js(int a,int b)
    {
    	if(a>b) swap(a,b);
    	return min(st[a][lg[b-a+1]],st[b-(1<<lg[b-a+1])+1][lg[b-a+1]]);
    }
    
    int main()
    {
    	n = read(),m = read(),s = read();
    	for(int i = 1;i < n;i ++){
    		int u = read(),v = read();
    		add(u,v);add(v,u);
    	}
    	cnt = 0;
    	dfs(s);
    	lg[1] = 0,lg[2] = 1;
    	for(int i = 3;i <= cnt;i ++) lg[i] = lg[i/2]+1;
    	for(int i = 1;i <= cnt;i ++) st[i][0] = arr[i];
    	for(int j = 1;j <= 30;j ++){
    		for(int i = 1;i +(1<<j)-1 <= cnt;i ++){
    			st[i][j] = min(st[i][j-1],st[i+(1<<j>>1)][j-1]);
    		}
    	}
    	for(int i = 1;i <= m;i ++){
    		int u = read(),v = read();
    		printf("%d
    ",pos[js(pre[u],pre[v])]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    html5内容嵌入元素
    thinkphp默认路径访问报错
    LNMP安装教程
    wampserver的mysql启动与环境变量设置
    http响应详解_韩顺平PHP视频听课笔记
    http请求详解,防盗链技术_韩顺平PHP视频听课笔记
    使用js写一个作用于xml文件的ajax
    使用js创建一个简单的ajax
    js写一个ajax错误规避
    使用js写一个原生态简单的ajax
  • 原文地址:https://www.cnblogs.com/nao-nao/p/13664134.html
Copyright © 2020-2023  润新知