求助LCA怎么有问题
查看原帖
求助LCA怎么有问题
987758
CaoSheng_zzz楼主2024/8/13 11:54
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <bitset>
#include <queue>
#include <map>
#define prt printf
#define ll long long
#define spc putchar(' ') 
#define ent putchar('\n')
using namespace std;
		
int read(){
	int f = 1 , k = 0;
	char c = getchar();
	while(c < '0' || c > '9'){
		if(c == '-') f = -1;
		c = getchar() ;
	}
	while(c >= '0' && c <= '9'){
		k = (k << 3) + (k << 1) + (c ^ 48);
		c = getchar() ;
	}
	return (f == 1 ? k : -k);
}
		
void output(int now){
	if(now < 0){
		putchar('-');
		output(- now);
	}
	else{
		if(now > 9) output(now / 10);
		putchar((now % 10) ^ 48);
	}
}
		
const int maxn = 2e5 + 1;
int h[maxn] , cnt = 0 , fa[maxn] , dis[maxn] , d[maxn] , anc[maxn][31];
struct Edge{
	int next , to , val;
}e[maxn << 1] ;
		
void add(int u , int v , int val) { e[++ cnt] = {h[u] , v , val} ; h[u] = cnt ; return ;}
		
int mn(int a , int b) { return a < b ? a : b ;}
		
void dfs(int u , int fa , int num){
	dis[u] = num ;
	d[u] = d[fa] + 1 , anc[u][0] = fa;
	for(int i=1 ; (1<<i)<=d[u] ; i++) anc[u][i] = anc[anc[u][i - 1]][i - 1];
	for(int i=h[u] ; i ; i=e[i].next){
		int v = e[i].to ;
		if(v == fa) continue ;
		dfs(v , u , num + e[i].val) ;
	}
}
		
int lca(int a , int b){
	if(d[a] < d[b]) swap(a , b) ;
	int k = d[a] ;
	for(int i=k ; i>=0 ; i--){
		if(d[a] - (1 << i) >= d[b]) a = anc[a][i] ;
	}
	if(a == b) return b ;
	for(int i=k ; i>=0 ; i--){
		if(anc[a][i] != 0 && anc[a][i] != anc[b][i]) { a = anc[a][i] , b = anc[b][i] ;}
	}
	return anc[a][0] ;
}
		
signed main(){
	int n = read() , q = read() , rt = read() ;
	for(int i=1 ; i<n ; i++){
		int u = read() , v = read() ;
		add(u , v , 0) , add(v , u , 0);
	}
	dfs(rt , rt , 0) ;
	while(q --){
		int a = read() , b = read() ;
//		int o = lca(a , b) ;
//		output(mn(dis[a] - dis[o] , dis[b] - dis[o])) , ent;
		output(lca(a , b)) , ent;
	}
	return 0;
}
/*
很显然对于查询 a,b 令 o = lca(a,b)  我们的答案就为 min(dis(o , a) , dis(o , b)) 我们可以处理每个节点到根节点的距离然后用 log n 求lca 最终时间复杂度 O(n + q \log (n))
*/
2024/8/13 11:54
加载中...