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;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值