LCA

倍增法:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll N=1e4+10;
 5 ll bit[30];
 6 ll pre[N][30];
 7 ll depth[N];
 8 vector<int>mp[N];
 9 
10 void init(int n){
11     bit[0]=1;
12     for(int i=1;i<=29;i++){
13         bit[i]=bit[i-1]*2;
14     }
15     for(int i=0;i<=n;i++){
16             mp[i].clear();
17     }
18     memset(pre,0,sizeof(pre));
19     memset(depth,0,sizeof(depth));
20 }
21 
22 void dfs(int s,int p){
23     pre[s][0]=p;
24     depth[s]=depth[p]+1;
25     for(int i=1;i<=29;i++){
26         pre[s][i]=pre[pre[s][i-1]][i-1];
27     }
28     for(int i=0;i<mp[s].size();i++){
29         if(mp[s][i]==p)    continue;
30         dfs(mp[s][i],s);
31     }
32 }
33 
34 int LCA(int a,int b){
35     if(depth[a]<depth[b]){
36         swap(a,b);
37     }
38     int dif=depth[a]-depth[b];
39     for(int i=29;i>=0;i--){
40         if(dif>=bit[i]){
41             a=pre[a][i];
42             dif-=bit[i];
43         }
44     }
45     if(a==b)return b;
46     for(int i=29;i>=0;i--){
47         if(depth[a]>=bit[i]&&pre[a][i]!=pre[b][i]){
48             a=pre[a][i];
49             b=pre[b][i];
50         }
51     }
52     return pre[a][0];
53 }
54 
55 int main(){
56     int t,n,a,b;
57     cin>>t;
58     while(t--){
59         map<int,int>mp1;
60         cin>>n;
61         init(n);
62         for(int i=1;i<=n-1;i++){
63             scanf("%d%d",&a,&b);
64             mp1[b]=1;
65             mp[a].push_back(b);
66             mp[b].push_back(a);
67         }
68         for(int i=1;i<=n;i++){
69             if(mp1[i]==0){
70                 dfs(i,0);
71                 break;
72             }
73         }
74         scanf("%d%d",&a,&b);
75         printf("%d\n",LCA(a,b));
76     }
77     
78     
79     return 0;
80 }

 

 

 

posted @ 2019-10-28 17:38  yya雨  阅读(129)  评论(0编辑  收藏  举报