zoukankan      html  css  js  c++  java
  • P3379 【模板】最近公共祖先(LCA)

    #include <bits/stdc++.h>
    using namespace std;
    
    int tot, n, m, s;
    const int N = 5e5 + 10, M = 1e6 + 10;
    int head[N], dep[N], fa[N][22];
    struct Edge{
    	int u, v, next;
    }edge[M];
    
    void add(int u, int v){
    	edge[tot].v = v;
    	edge[tot].next = head[u];
    	head[u] = tot ++;
    }
    
    void dfs(int now, int pre){
    	dep[now] = dep[pre] + 1;
    	fa[now][0] = pre;
    	for(int i = head[now]; i != -1; i = edge[i].next){
    		int v = edge[i].v;
    		if(v != pre)
    			dfs(v, now);
    	}
    }
    
    int getlca(int u, int v){
    	if(dep[u] < dep[v])
    		swap(u, v);
    	while(dep[u] > dep[v])
    		u = fa[u][(int)log2(dep[u] - dep[v])];
    	if(u == v)
    		return u;
    	for(int j = 20; j >= 0; j --)
    		if(fa[u][j] != fa[v][j])
    			u = fa[u][j], v = fa[v][j];
    	return fa[u][0];
    }
    int main(){
    	cin >> n >> m >> s;
    	memset(head, -1, sizeof head);
    	for(int i = 1; i < n; i ++){
    		int a, b;
    		cin >> a >> b;
    		add(a, b);
    		add(b, a);
    	}
    
    	
    	dfs(s, 0);
    
    	for(int j = 1; j <= 20; j ++)			//次数从小到大更新 
    		for(int i = 1; i <= n; i ++)
    			fa[i][j] = fa[fa[i][j - 1]][j - 1];
    	
    	for(int i = 1; i <= m; i ++){
    		int a, b;
    		cin >> a >> b;
    		int ans = getlca(a, b);
    		cout << ans << endl;
    	}
    	return 0;
    } 
    
  • 相关阅读:
    Chrome开发者工具详解(1)
    Chrome开发者工具详解(2)
    Ubuntu ADSL拨号上网
    Bash中单引号和双引号的区别
    建立菜单
    波浪号和Hyphen扩展
    标准IO和重定向
    Bash变量扩展修改符
    mysql主键约束和唯一性约束
    Here文档
  • 原文地址:https://www.cnblogs.com/pureayu/p/14972149.html
Copyright © 2011-2022 走看看