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


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com