Nearest Common Ancestors
题意:找两个点公共祖先,裸题。
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 ",x); 31 } 32 }
倍增法
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 ",lca(u,v)); 93 } 94 return 0; 95 }