http://poj.org/problem?id=1330

const int MM = 22222; int N, in[MM], root; int head[MM],NE; struct Edge{ int u,v,next; }edge[MM]; bool vis[MM]; int ief,level; int dp[MM][17]; //节点数*2 int E[MM], L[MM], H[MM]; //节点数*2 int log_2(int x) { int res=-1; while(x) x>>=1,res++; return res; } void add_edge(int u,int v) { edge[NE].u=u, edge[NE].v=v; edge[NE].next=head[u], head[u]=NE++; } void get_data() { int i,j,k,x,y; scanf("%d",&N); NE=0; memset(head,-1,sizeof(head)); memset(in,0,sizeof(in)); for(i=1;i<N;i++) { scanf("%d%d",&x,&y); in[y]++; add_edge(x,y), add_edge(y,x); } for(i=1;i<=N;i++) if(in[i]==0) {root=i;break;} } void dfs(int u) { int i,j,k,v; E[++ief]=u; H[u]=ief; L[ief]=++level; for(i=head[u];i!=-1;i=edge[i].next) { v=edge[i].v; if(!vis[v]) { vis[v]=true; dfs(v); E[++ief]=u; L[ief]=--level; } } } void init_rmq() { int i,j,k,lim; for(i=1;i<=ief;i++) dp[i][0]=i; k=log_2(ief); for(i=1;i<=k;i++) { lim=ief-(1<<i)+1; for(j=1;j<=lim;j++) { if(L[dp[j][i-1]]>L[dp[j+(1<<(i-1))][i-1]]) dp[j][i]=dp[j+(1<<(i-1))][i-1]; else dp[j][i]=dp[j][i-1]; } } } int query(int x,int y) { if(x>y) swap(x,y); int k=log_2(y-x+1); if(L[dp[x][k]]>L[dp[y-(1<<k)+1][k]]) return dp[y-(1<<k)+1][k]; else return dp[x][k]; } void solve() { int i,j,k,x,y; memset(vis,false,sizeof(vis)); vis[1]=true, level=ief=0; dfs(root); init_rmq(); scanf("%d%d",&x,&y); printf("%d\n",E[query(H[x],H[y])]); } int main() { int ca; scanf("%d",&ca); while(ca--) get_data(),solve(); return 0; }