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 }