POJ1330(Nearest Common Ancestors)

求一棵树中2个点的最近公共祖先。

我的做法:用并查集求出每个结点的深度,然后递归求最近公共祖先。

View Code
 1 #include <stdio.h>

 2 #define N 10001

 3 int fa[N],p[N],d[N],n;

 4 void make_set()

 5 {

 6   for(int i=1;i<=n;i++)

 7   {

 8     p[i]=i;

 9     d[i]=0;

10   }

11 }

12 int find_set(int i)

13 {

14   int pi=p[i];

15   if(pi!=i) p[i]=find_set(p[i]);

16   if(pi!=p[i])  d[i]+=d[pi];

17   return p[i];

18 }

19 void union_set(int i,int j)

20 {

21   int pi=find_set(i),pj=find_set(j);

22   fa[j]=i;

23   p[pj]=pi;

24   d[pj]=-d[j]+1+d[i];

25 }

26 int lca(int i,int j)

27 {

28   if(i==j)  return i;

29   if(d[i]>d[j]) return lca(fa[i],j);

30   if(d[i]<d[j]) return lca(i,fa[j]);

31   return lca(fa[i],fa[j]);

32 }

33 int main()

34 {

35   int t,i,a,b;

36   scanf("%d",&t);

37   while(t--)

38   {

39     scanf("%d",&n);

40     make_set();

41     for(i=0;i<n-1;i++)

42     {

43       scanf("%d%d",&a,&b);

44       union_set(a,b);

45     }

46     scanf("%d%d",&a,&b);

47     printf("%d\n",lca(a,b));

48   }

49   return 0;

50 }

 

你可能感兴趣的:(REST)