POJ1330最近公共祖先

        今天做完了POJ的第1330题,AC之后发现性能也不错,特把思路重新捋一遍,把结果与大家分享。

一、题意解析

输入为一颗树的结点数及其每一条边的连线。要求输出给定两个结点的最近公共祖先编号。

二、结题思路

之前刚刚做了POJ的1183题,其实本题要比1183简单许多。由于每一行输入指定唯一的一条边且第一个结点为第二个结点的父亲结点。所以可定义数组(a),用来保存每个结点的父结点编号。此时,a[x]为编号为x的结点的父节点的编号。则循环令x=a[x]可求出x的所有祖先,此时求最近公共祖先便为求出两个结点最先共有的一个x。具体步骤为:首先分别计算出x与y的在树中的“层数”,层数=祖先数+。则本题目的变为从低层到高层(根节点)方向求在一层中的结点是否相同。

其实自己感觉也没有太说清楚。也没有花太多时间,只是想把自己做的不错的结果与大家分享下。

三、AC代码

#include <stdio.h>
#include <string.h>


#define N 10001
int a[N] = {0}; //Record the parent of each node.


void build_tree(int x, int y)
{
a[y] = x;
}


int check_anc(int x, int count)
{
int anc;
anc = a[x];
count++;
if(anc != 0)
check_anc(anc,count);
else
return count;
}


int find_anc(int x, int y, int count_x, int count_y)
{
int dif = count_x - count_y;
int temp, i, temp1, temp2;
if(dif > 0)
{
temp1 = x;
temp2 = y;
}
else
{
dif = 0 - dif;
temp1 = y;
temp2 = x;
}
for(i = 0; i < dif; i++)
temp1 = a[temp1];

while(temp1 != 0)
{
if(temp1 == temp2)
break;
temp1 = a[temp1];
temp2 = a[temp2];
}

return temp1;
}
int judge_node(int x, int y)
{
int anc_x, anc_y;
int count_x, count_y;

count_x = check_anc(x,0);
count_y = check_anc(y,0);

int result = find_anc(x,y,count_x,count_y);

}


int main()
{
int i,n,x,y,res;
scanf("%d",&i);

for(; i > 0; i--) //For each tree.
{
scanf("%d",&n);
for(; n > 1; n--)
{
scanf("%d%d",&x,&y);
build_tree(x,y);
}
scanf("%d%d",&x,&y);
res = judge_node(x,y);
printf("%d\n",res);
memset(a,0,N*4);
}
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值