Nearest Common Ancestors (LCA)

裸的lca,找最近公共祖先, 他给你了父亲节点,只要根据给的数据建树就可以了。

这个题写的时候出了bug,dfs() 的时候,树的顶端的父亲节点是否设成语顶端一样。如果一样,dep可以memset(dep,0)

如果不一样,那么,dep 的值 ,顶端的节点和 父亲节点的dep 一定不能一样。如果顶端值为0,,其父亲节点一定不能为0

否则出bug

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#define mem(x,v) memset(x,v,sizeof(x)) 
#define rep(i,a,b)  for (int i = a; i < b; i++)
#define per(i,a,b)  for (int i = a; i > b; i--)
using namespace std;
typedef long long LL;
const double EPS = 1e-10;
const int INF = 0x3f3f3f3f;
const int N = 2e4+10;
int n,in[N];
int f[N][20],dep[N];
int Head[N],cnt,p[N],Next[N];
void Add(int u, int v){
	cnt++;
	Next[cnt] = Head[u];
	Head[u] = cnt;
	p[cnt] = v;
	return;
}
void dfs(int u, int fa, int deep){
	f[u][0] = fa;
	dep[u] = deep;
	for (int i = 1; i < 20; i++)
		f[u][i] = f[f[u][i-1]][i-1];
	for (int i = Head[u]; i != -1; i = Next[i]){
		int v = p[i];
		if (v == fa) continue;
		dfs(v,u,deep+1);
	}
	return;
}
int lca(int x, int y){
	if (dep[x] < dep[y]) swap(x,y);
	per(i,19,-1)
	if (dep[f[x][i]] >= dep[y]) x = f[x][i];
	if (x == y) return x;
	per(i,19,-1) 
	if (f[x][i] != f[y][i]) {
		x = f[x][i];
		y = f[y][i];
	}
	return f[x][0];
}

int main(){
	int T;
	cin>>T;
	while(T--){
		mem(in,0); mem(Head,-1); cnt = -1;
		scanf("%d",&n);
		rep(i,1,n){
			int x,y;
			scanf("%d%d",&x,&y);
		    Add(x,y);
			in[y]++;
		}
		int s;
		rep(i,1,n+1) if (in[i] == 0) {
			s = i; break;
		}
		mem(f,0); mem(dep,-1);
		dfs(s,0,0); //这个地方出了bug
		int x,y;
		scanf("%d%d",&x,&y);
		printf("%d\n",lca(x,y));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/kidsummer/article/details/81557076
今日推荐