POJ 1330 Nearest Common Ancestors (LCA,dfs+ST在线算法)

这题只是询问 一组u,v的LCA

但是要判断root 是哪个。

在线做法:

    

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<cmath>
 6 #include<vector>
 7 #include<queue>
 8 #include<map>
 9 #define N 11111
10 #define LN 20
11 using namespace std;
12 int dp[N][LN];
13 vector<int> mp[N];
14 int dep[N];
15 
16 void dfs(int u,int fa,int level)
17 {
18   dp[u][0]=fa;
19   dep[u]=level;
20   for (int i=0;i<mp[u].size();i++)
21   {
22     int v=mp[u][i];
23     if (fa==v) continue;
24     dfs(v,u,level+1);
25   }
26 }
27 
28 
29 int lca(int u,int v)
30 {
31   if  (dep[u]<dep[v]) swap(u,v);
32   int dif=dep[u]-dep[v];
33   for (int i=0;i<LN;i++)
34   if ((dif>>i)&1) u=dp[u][i];
35 
36   if (u==v) return u;
37   
38   for (int i=LN-1;i>=0;i--)
39   if (dp[u][i]!=dp[v][i]) u=dp[u][i],v=dp[v][i];
40   
41   return dp[u][0];
42 }
43 
44 
45 int f[N];
46 int main()
47 {
48   int T;
49   scanf("%d",&T);
50   while (T--)
51   {
52       int n;
53       scanf("%d",&n);
54       for (int i=0;i<=n;i++) mp[i].clear();
55       memset(f,0,sizeof(f));
56       for (int i=1;i<n;i++)
57       {
58         int x,y;
59         scanf("%d%d",&x,&y);
60         f[y]=x;
61         mp[x].push_back(y);
62         mp[y].push_back(x);
63       }
64       int root=1;
65       for (int i=1;i<=n;i++)
66       if (f[i]==0)
67       {
68         root=i;
69         break;
70       }
71       dfs(root,0,0);
72       for (int i=1;i<LN;i++)
73       for (int j=1;j<=n;j++)
74       dp[j][i]=dp[ dp[j][i-1]][i-1];
75 
76       int x,y;
77       scanf("%d%d",&x,&y);
78       printf("%d
",lca(x,y));
79   }
80   return 0;
81 }
原文地址:https://www.cnblogs.com/forgot93/p/4366940.html