Nearest Common Ancestors POJ - 1330

Nearest Common Ancestors

POJ - 1330

题意:找两个点公共祖先,裸题。

 

 1 #include <cstdio>
 2 #include <cstring>
 3 const int maxn=10010;
 4 
 5 int f[maxn],vis[maxn];
 6 
 7 int main(){
 8     int n,t;
 9    // freopen("in.txt","r",stdin);
10     scanf("%d",&t);
11     while(t--){
12         scanf("%d",&n);
13         int u,v;
14         memset(vis,0,sizeof(vis));
15         memset(f,0,sizeof(f));
16         for(int i=1;i<n;i++){
17             scanf("%d%d",&u,&v);
18             f[v]=u;
19         }
20         scanf("%d%d",&u,&v);
21         int x=u;
22         while(x){
23             vis[x]=1;
24             x=f[x];
25         }
26         x=v;
27         while(x&&!vis[x]){
28             x=f[x];
29         }
30         printf("%d\n",x);
31     }
32 }
View Code

 

倍增法

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 using namespace std;
 5 
 6 const int maxn=10010;
 7 
 8 int tot;
 9 int fr[maxn],dep[maxn<<1],p[maxn<<1];
10 int dp[maxn<<1][30],deg[maxn];
11 struct Edge{
12     int v,nex;
13 }e[maxn<<1];
14 int head[maxn];
15 int cnt=0;
16 void init(){
17     tot=0;
18     memset(head,-1,sizeof(head));
19     memset(deg,0,sizeof(deg));
20     cnt=0;
21 }
22 void add(int u,int v){
23     e[cnt].v=v;
24     e[cnt].nex=head[u];
25     head[u]=cnt++;
26 }
27 
28 void dfs(int u,int f,int d){
29     tot++;
30     p[tot]=u;
31     dep[tot]=d;
32     fr[u]=tot;
33     for(int i=head[u];~i;i=e[i].nex){
34         int v=e[i].v;
35         if(v==f) continue;
36         dfs(v,u,d+1);
37         tot++;
38         p[tot]=u;
39         dep[tot]=d;
40     }
41     return ;
42 }
43 
44 void RMQ_init(int n){
45     int k=1;
46     while((1<<k+1)<n) k++;
47     for(int i=1;i<=n;i++) dp[i][0]=i;
48     for(int j=1;j<=k;j++){
49         for(int i=1;i+(1<<j)-1<=n;i++){
50             int a=dp[i][j-1];
51             int b=dp[i+(1<<j-1)][j-1];
52             if(dep[a]<dep[b]) dp[i][j]=a;
53             else dp[i][j]=b;
54         }
55     }
56     return ;
57 }
58 
59 int rmq(int u,int v){
60     int k=1;
61     while((1<<k+1)<v-u+1) k++;
62     int a=dp[u][k];
63     int b=dp[v-(1<<k)+1][k];
64     if(dep[a]<dep[b]) return a;
65     else return b;
66 }
67 
68 int lca(int u,int v){
69     u=fr[u];
70     v=fr[v];
71     if(u>v) swap(u,v);
72     int rt=rmq(u,v);
73     return p[rt];
74 }
75 
76 int main(){
77     int n,t;
78    // freopen("in.txt","r",stdin);
79     scanf("%d",&t);
80     while(t--){
81         init();
82         scanf("%d",&n);
83         int u,v;
84         for(int i=1;i<n;i++){
85             scanf("%d%d",&u,&v);
86             add(u,v);
87             deg[v]++;
88         }
89         for(int i=1;i<=n;i++) if(!deg[i]) dfs(i,-1,1);
90         RMQ_init(tot);
91         scanf("%d%d",&u,&v);
92         printf("%d\n",lca(u,v));
93     }
94     return 0;
95 }
View Code

 

posted @ 2017-09-06 17:33  yijiull  阅读(133)  评论(0编辑  收藏  举报