倍增写法只过了两个点 求指教或者神奇数据
查看原帖
倍增写法只过了两个点 求指教或者神奇数据
294454
Just_A_King楼主2023/4/12 15:18
#include<bits/stdc++.h>

using namespace std;

const int N = 5e5 + 3, M = 1e6 + 3, P = 24;

int n, m, s;

int head[N], e[M], nxt[M], tot;
void addline(int u, int v) {
	e[++tot] = v;
	nxt[tot] = head[u];
	head[u] = tot;
}

int depth[N], fa[N][P];
void dfs(int u, int father) {
	depth[u] = depth[father] + 1;
	fa[u][0] = father;
	for(int i = head[u]; i; i = nxt[i]) {
		int v = e[i];
		if(v == father) continue;
		dfs(v, u);
	}
}

void init_lca() {
	for(int i = 1; i <= n; i++)
		for(int j = 1; j < P; j++)
			fa[i][j] = fa[fa[i][j - 1]][j - 1];
}

int get_lca(int a, int b) {
	if(depth[a] < depth[b]) swap(a, b);
	for(int i = P - 1; i >= 0; i--) {
		if(depth[fa[a][i]] >= depth[b])
			a = fa[a][i];
		if(depth[a] == depth[b]) break;
	}
	if(a == b) return a;
	//cout << " t " << a << " " << b << endl;
	for(int i = P - 1; i >= 0; i--) {
		if(fa[a][i] != fa[b][i]) {
			a = fa[a][i];
			b = fa[b][i];
		}
	}
	return fa[a][0];
}

int main() {
	//freopen("P3379_1.in", "r", stdin);
	//ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n >> m >> s;
	for(int i = 1; i < n; i++) {
		int u, v; cin >> u >> v;
		addline(u, v);
		addline(v, u);
	}

	dfs(s, 0);
	init_lca();
	
	/*
	for(int i = 1; i <= n; i++) {
		for(int j = 0; j < P; j++)
			cout << fa[i][j] << " ";
		cout << endl;
	}
	*/
	
	for(int i = 1; i <= m; i++) {
		int a, b; cin >> a >> b;
		cout << get_lca(a, b) << "\n";
	}
	
	return 0;
}
2023/4/12 15:18
加载中...