模板 最近公共祖先(LCA)

【模板】最近公共祖先(LCA)为例题

倍增法

#include<bits/stdc++.h>

using namespace std;
using ll = long long;

int main() {
	ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m, s;
    cin >> n >> m >> s;

    vector<vector<int>> adj(n + 1);
    for(int i = 1; i < n; i++) {
    	int u, v;
    	cin >> u >> v;
    	adj[u].push_back(v);
    	adj[v].push_back(u);
    }

    vector<int> dep(n + 1);
    vector<array<int, 22>> fa(n + 1);
    auto dfs = [&](auto self, int u, int p) -> void {
    	dep[u] = dep[p] + 1;
    	fa[u][0] = p;
    	for(int i = 1; (1 << i) <= dep[u]; i++) {
    		fa[u][i] = fa[fa[u][i - 1]][i - 1];
    	}
    	for(int v : adj[u]) {
    		if(v == p) continue;
    		self(self, v, u);
    	}
    };
    dfs(dfs, s, 0);

    while(m--) {
    	int u, v;
    	cin >> u >> v;

    	if(dep[u] < dep[v]) swap(u, v);
    	for(int i = 19; i >= 0; i--) {
    		if(dep[fa[u][i]] >= dep[v]) {
    			u = fa[u][i];
    		}
    	}
    	if(u == v) {
    		cout << u << "\n";
    		continue;
    	}
    	for(int i = 19; i >= 0; i--) {
    		if(fa[u][i] != fa[v][i]) {
    			u = fa[u][i];
    			v = fa[v][i];
    		}
    	}

    	cout << fa[u][0] << "\n"; 
    }

    return 0;
}
posted @ 2023-07-31 02:21  wuyoudexian  阅读(42)  评论(0)    收藏  举报