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\n",lca(x,y)); 79 } 80 return 0; 81 }
随性Code