zoukankan      html  css  js  c++  java
  • 倍增最近公共祖先(LCA)

    倍增最近公共祖先(LCA)

    标签(空格分隔): 模板

    #include <bits/stdc++.h>
    using namespace std;
    
    
    const int MAXN = 5e5 + 50;
    int n, m, s;
    int fa[MAXN][50], lg[MAXN], dep[MAXN];
    
    vector<int> e[MAXN];
    
    
    inline int read()
    {
    	int res = 0;
    	char ch = getchar();
    	
    	while(48 > ch || ch > 57){
    		ch = getchar();
    	}
    	
    	while(48 <= ch && ch <= 57){
    		res = (res << 3) + (res << 1) + (ch - 48);
    		ch = getchar();
    	}
    	
    	return res;
    }
    
    void add_edge(int u, int v)
    {
    	e[u].push_back(v);
    	e[v].push_back(u);
    	
    	return; 
    }
    
    void build_lca(int now)
    {
    //	cout << "*";
    	for(int i = 1; i <= 30 && fa[now][i - 1]; i ++ )
    		fa[now][i] = fa[fa[now][i - 1]][i - 1];
    	
    	for(int v : e[now]){
    		if(v == fa[now][0])   continue;
    		
    		dep[v] = dep[now] + 1;
    		fa[v][0] = now;
    		build_lca(v);
    	} 
    	
    	return;
    }
    
    int get_lca(int u, int v)
    {
    	if(dep[u] < dep[v])  swap(u, v);
    	
    	while(dep[u] > dep[v])
    		u = fa[u][lg[dep[u] - dep[v]] - 1];
    	if(u == v)	return u;
    	
    	for(int i = lg[dep[u]]; i >= 0; i --){
    		if(fa[u][i] != fa[v][i])
    			u = fa[u][i], v = fa[v][i];
    	}
    	
    	return fa[u][0];
    }
    int main()
    {
    	
    	n = read(), m = read(), s = read();
    	
    	for(int i = 0; i < n - 1; i ++){
    		int u = read(), v = read();
    		add_edge(u, v);
    	} 
    	
    	
    	build_lca(s); 
    	
    	for(int i = 1; i <= n; i ++)
    		lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
    	for(int i = 0; i < m; i ++){
    		int u = read(), v = read();
    		printf("%d
    ", get_lca(u, v));
    	}
    	return 0;
    }
  • 相关阅读:
    又一道简单的题
    atoi函数的使用(将字符串转换成整型数)
    【贪心】Radar Installation(POJ1328)
    【BFS】鸣人与佐助
    谍报分析
    适配器模式(C++实现)
    策略模式(C++)
    工厂模式(C++实现)
    桥接模式(C++实现)
    关于getMemory函数的几点思考
  • 原文地址:https://www.cnblogs.com/satchelpp/p/14116981.html
Copyright © 2011-2022 走看看