倍增LCA求调,输出全0
查看原帖
倍增LCA求调,输出全0
313137
qqqqq111楼主2022/2/19 16:58

rt

#include <cstdio>
#include <queue>
#include <iostream>
#include <cmath>

using namespace std;

#define M N-1
#define N 500005

int f[N][50];
int d[N];//深度
int rt;//root
int t;//log2n

struct node {
	int to, next;
}edge[M];
int head[N], tot;//链式前向星

void add(int u, int v) {//连边
	edge[++tot]={v, head[u]};
	head[u]=tot;
}
void bfs() {//预处理d和f数组
	queue<int> q;
	d[rt]=1;
	q.push(rt);
	while(!q.empty()) {
		int x=q.front();
		q.pop();
		for(int i=head[x]; i; i=edge[i].next) {
			int y=edge[i].to;
			if(d[y])
				continue;
			d[y]=d[x]+1;
			f[y][0]=x;
			for(int j=1; j<=t; j++) {
				f[y][j]=f[f[y][j-1]][j-1];
			}
			q.push(y);
		}
	}
}
int lca(int x, int y) {//lca
	if(d[x]<d[y])
		swap(x, y);
	for(int i=t; i>=0; i--) {
		if(d[f[x][i]]>=d[y]) {
			x=f[x][i];
		}
	}
	if(x==y)
		return y;
	for(int i=t; i>=0; i--) {
		if(f[x][i]!=f[y][i]) {
			x=f[x][i];
			y=f[y][i];
		}
	}
	return f[x][0];
}

int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	scanf("%d", &rt);
	t=(int)log2(n)+1;
	for(int i=1; i<n; i++) {
		int u, v;
		scanf("%d%d", &u, &v);
		add(u, v);
	}
	bfs();
	while(m--) {
		int a, b;
		scanf("%d%d", &a, &b);
		printf("%d\n", lca(a, b));
	}
	return 0;
}
2022/2/19 16:58
加载中...