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 }

 

posted @ 2012-07-03 18:29  BeatLJ  阅读(238)  评论(0编辑  收藏  举报